diff --git a/cdi/injection/pom.xml b/cdi/injection/pom.xml
new file mode 100644
index 000000000..d8a498fb1
--- /dev/null
+++ b/cdi/injection/pom.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+ org.gatein.cdi
+ gatein-cdi-parent
+ 3.6.0.Beta02-SNAPSHOT
+
+ 4.0.0
+
+ gatein-cdi-injection
+ jar
+ GateIn CDI Portlet and Filter Injection
+
+
+
+ javax.enterprise
+ cdi-api
+ provided
+
+
+ javax.portlet
+ portlet-api
+ provided
+
+
+ javax.servlet
+ javax.servlet-api
+ provided
+
+
+ org.gatein.pc
+ pc-portlet
+
+
+
+
diff --git a/cdi/injection/src/main/java/org/gatein/cdi/CDIInjectionListener.java b/cdi/injection/src/main/java/org/gatein/cdi/CDIInjectionListener.java
new file mode 100644
index 000000000..9a5825a6d
--- /dev/null
+++ b/cdi/injection/src/main/java/org/gatein/cdi/CDIInjectionListener.java
@@ -0,0 +1,223 @@
+package org.gatein.cdi;
+
+import org.gatein.common.logging.Logger;
+import org.gatein.common.logging.LoggerFactory;
+import org.gatein.pc.portlet.container.PortletApplication;
+import org.gatein.pc.portlet.container.managed.LifeCycleStatus;
+import org.gatein.pc.portlet.container.managed.ManagedObject;
+import org.gatein.pc.portlet.container.managed.ManagedObjectAddedEvent;
+import org.gatein.pc.portlet.container.managed.ManagedObjectLifeCycleEvent;
+import org.gatein.pc.portlet.container.managed.ManagedObjectRegistryEvent;
+import org.gatein.pc.portlet.container.managed.ManagedObjectRegistryEventListener;
+import org.gatein.pc.portlet.container.managed.ManagedPortletContainer;
+import org.gatein.pc.portlet.container.managed.ManagedPortletFilter;
+import org.gatein.pc.portlet.impl.jsr168.PortletFilterImpl;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.InjectionTarget;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.portlet.Portlet;
+import javax.portlet.filter.ActionFilter;
+import javax.portlet.filter.EventFilter;
+import javax.portlet.filter.PortletFilter;
+import javax.portlet.filter.RenderFilter;
+import javax.portlet.filter.ResourceFilter;
+import javax.servlet.ServletContext;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author Ken Finnigan
+ */
+public class CDIInjectionListener implements ManagedObjectRegistryEventListener {
+ private final Logger log = LoggerFactory.getLogger(CDIInjectionListener.class);
+
+ private static final String BEAN_MGR_ATTRIBUTE = "javax.enterprise.inject.spi.BeanManager";
+ private static final String SERVLET_BEAN_MGR_ATTRIBUTE = "org.jboss.weld.environment.servlet.javax.enterprise.inject.spi.BeanManager";
+
+ private Map cdiMetaDataMap = new ConcurrentHashMap();
+
+ private List> filterClasses = new ArrayList>();
+
+ public CDIInjectionListener() {
+ filterClasses.add(ActionFilter.class);
+ filterClasses.add(EventFilter.class);
+ filterClasses.add(RenderFilter.class);
+ filterClasses.add(ResourceFilter.class);
+ }
+
+ @Override
+ public void onEvent(ManagedObjectRegistryEvent event) {
+
+ if (event instanceof ManagedObjectAddedEvent) {
+ // Track whether a portletContainer or portletFilter needs CDI injection
+
+ ManagedObject managedObject = ((ManagedObjectAddedEvent) event).getManagedObject();
+
+ if (managedObject instanceof ManagedPortletContainer) {
+
+ ManagedPortletContainer managedPortletContainer = (ManagedPortletContainer) managedObject;
+ PortletApplication portletApp = managedPortletContainer.getManagedPortletApplication().getPortletApplication();
+
+ createMetaData(managedPortletContainer.getId(), portletApp);
+
+ } else if (managedObject instanceof ManagedPortletFilter) {
+
+ ManagedPortletFilter managedPortletFilter = (ManagedPortletFilter) managedObject;
+ PortletApplication portletApp = managedPortletFilter.getManagedPortletApplication().getPortletApplication();
+
+ createMetaData(managedPortletFilter.getId(), portletApp);
+ }
+
+ } else if (event instanceof ManagedObjectLifeCycleEvent) {
+
+ ManagedObjectLifeCycleEvent lifeCycleEvent = (ManagedObjectLifeCycleEvent) event;
+ ManagedObject managedObject = lifeCycleEvent.getManagedObject();
+ LifeCycleStatus status = lifeCycleEvent.getStatus();
+
+ if (managedObject instanceof ManagedPortletContainer) {
+
+ if (LifeCycleStatus.STARTED == status || LifeCycleStatus.INITIALIZED == status) {
+ return;
+ }
+
+ ManagedPortletContainer managedPortletContainer = (ManagedPortletContainer) managedObject;
+ CDIMetaData cdiMetaData = cdiMetaDataMap.get(managedPortletContainer.getId());
+
+ if (!cdiMetaData.cdiInjectionEnabled) {
+ return;
+ }
+
+ Portlet portlet = managedPortletContainer.getPortletInstance();
+
+ if (null != portlet) {
+ if (null != portlet.getClass() && "javax.portlet.faces.GenericFacesPortlet".equals(portlet.getClass().getName())) {
+ // Only perform injection on non JSF portlets
+ cdiMetaData.cdiInjectionEnabled = false;
+ cdiMetaDataMap.put(cdiMetaData.key, cdiMetaData);
+ return;
+ }
+
+ PortletApplication portletApp = managedPortletContainer.getManagedPortletApplication().getPortletApplication();
+
+ if (!cdiMetaData.injectionPerformed) {
+ performInjection(portlet, cdiMetaData, portletApp.getContext().getServletContext());
+ } else {
+ performCleanup(portlet, cdiMetaData, portletApp.getContext().getServletContext());
+ }
+ }
+ } else if (managedObject instanceof ManagedPortletFilter) {
+
+ if (LifeCycleStatus.INITIALIZED == status) {
+ return;
+ }
+
+ ManagedPortletFilter managedPortletFilter = (ManagedPortletFilter) managedObject;
+ CDIMetaData cdiMetaData = cdiMetaDataMap.get(managedPortletFilter.getId());
+
+ if (!cdiMetaData.cdiInjectionEnabled) {
+ return;
+ }
+
+ PortletFilterImpl portletFilterImpl = (PortletFilterImpl) managedPortletFilter.getPortletFilter();
+ PortletFilter portletFilterInstance;
+
+ for (Class type : filterClasses) {
+ portletFilterInstance = (PortletFilter) portletFilterImpl.instance(type);
+
+ if (null != portletFilterInstance) {
+ PortletApplication portletApp = managedPortletFilter.getManagedPortletApplication().getPortletApplication();
+
+ if (LifeCycleStatus.STARTED == status && !cdiMetaData.injectionPerformed) {
+ performInjection(portletFilterInstance, cdiMetaData, portletApp.getContext().getServletContext());
+ } else if (LifeCycleStatus.CREATED == status && cdiMetaData.injectionPerformed) {
+ performCleanup(portletFilterInstance, cdiMetaData, portletApp.getContext().getServletContext());
+ }
+
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ private void createMetaData(String id, PortletApplication portletApp) {
+ CDIMetaData metaData = new CDIMetaData();
+ metaData.key = id;
+
+ if (null != portletApp.getContext().getServletContext().getAttribute(BEAN_MGR_ATTRIBUTE)) {
+ metaData.cdiInjectionEnabled = true;
+ } else {
+ Object beanManager = portletApp.getContext().getServletContext().getAttribute(SERVLET_BEAN_MGR_ATTRIBUTE);
+ if (null != beanManager) {
+ metaData.cdiInjectionEnabled = true;
+ portletApp.getContext().getServletContext().setAttribute(BEAN_MGR_ATTRIBUTE, beanManager);
+ }
+ }
+
+ cdiMetaDataMap.put(id, metaData);
+ }
+
+ private void performInjection(Object instance, CDIMetaData metaData, ServletContext servletContext) {
+ // Perform CDI injection
+ Object beanManagerObject = servletContext.getAttribute(BEAN_MGR_ATTRIBUTE);
+
+ if (null == beanManagerObject) {
+ log.error("Unable to retrieve BeanManager from ServletContext");
+ return;
+ }
+
+ ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(servletContext.getClassLoader());
+
+ BeanManager beanManager = (BeanManager) beanManagerObject;
+ CreationalContext creationalContext = beanManager.createCreationalContext(null);
+ InjectionTarget injectionTarget = beanManager.createInjectionTarget(beanManager.createAnnotatedType(instance.getClass()));
+ injectionTarget.inject(instance, creationalContext);
+
+ Thread.currentThread().setContextClassLoader(oldCL);
+
+ metaData.injectionPerformed = true;
+ metaData.creationalContext = creationalContext;
+ metaData.injectionTarget = injectionTarget;
+
+ cdiMetaDataMap.put(metaData.key, metaData);
+ }
+
+ private void performCleanup(Object instance, CDIMetaData metaData, ServletContext servletContext) {
+ // Perform CDI cleanup
+ InjectionTarget injectionTarget = metaData.injectionTarget;
+ CreationalContext creationalContext = metaData.creationalContext;
+
+ ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(servletContext.getClassLoader());
+
+ if (null != injectionTarget) {
+ injectionTarget.dispose(instance);
+ metaData.injectionTarget = null;
+ }
+
+ if (null != creationalContext) {
+ creationalContext.release();
+ metaData.creationalContext = null;
+ }
+
+ Thread.currentThread().setContextClassLoader(oldCL);
+
+ metaData.injectionPerformed = false;
+ cdiMetaDataMap.put(metaData.key, metaData);
+ }
+
+ private class CDIMetaData {
+ private String key;
+ private boolean cdiInjectionEnabled = false;
+ private boolean injectionPerformed = false;
+ private InjectionTarget injectionTarget;
+ private CreationalContext creationalContext;
+ }
+}
diff --git a/cdi/pom.xml b/cdi/pom.xml
new file mode 100644
index 000000000..949e4ce82
--- /dev/null
+++ b/cdi/pom.xml
@@ -0,0 +1,46 @@
+
+
+
+ 4.0.0
+
+ GateIn CDI Enhancements
+
+ org.gatein.cdi
+ gatein-cdi-parent
+ 3.6.0.Beta02-SNAPSHOT
+
+ pom
+
+
+ org.gatein.portal
+ exo.portal.parent
+ 3.6.0.Beta02-SNAPSHOT
+
+
+ GateIn CDI Enhancements parent
+
+
+ injection
+
+
diff --git a/component/pc/pom.xml b/component/pc/pom.xml
index e8a87764c..9016089a5 100644
--- a/component/pc/pom.xml
+++ b/component/pc/pom.xml
@@ -1,17 +1,17 @@
diff --git a/packaging/jboss-as7/modules/src/main/resources/modules/org/gatein/lib/main/module.xml b/packaging/jboss-as7/modules/src/main/resources/modules/org/gatein/lib/main/module.xml
index 8cd5060f5..0836853b6 100644
--- a/packaging/jboss-as7/modules/src/main/resources/modules/org/gatein/lib/main/module.xml
+++ b/packaging/jboss-as7/modules/src/main/resources/modules/org/gatein/lib/main/module.xml
@@ -77,6 +77,7 @@
+
diff --git a/packaging/tomcat/pkg/pom.xml b/packaging/tomcat/pkg/pom.xml
index 3380066de..6a90cf3da 100644
--- a/packaging/tomcat/pkg/pom.xml
+++ b/packaging/tomcat/pkg/pom.xml
@@ -364,6 +364,16 @@
jboss-dmr
+
+
+ org.gatein.cdi
+ gatein-cdi-injection
+
+
+ javax.enterprise
+ cdi-api
+
+
org.staxnav
diff --git a/pom.xml b/pom.xml
index e5db22094..4e873194a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -68,6 +68,7 @@
5.1.7.Final
1.3.15.GA
+ 1.0-SP4
4.1.2
@@ -132,6 +133,7 @@
starter
wsrp-integration
mobile-integration
+ cdi
packaging
testsuite
@@ -1074,6 +1076,13 @@
${version.picketlink.fed}
+
+
+ org.gatein.cdi
+ gatein-cdi-injection
+ ${project.version}
+
+
org.infinispan
@@ -1105,6 +1114,11 @@
httpcore
${version.org.apache.httpcomponents.httpcore}
+
+ javax.enterprise
+ cdi-api
+ ${version.cdi.spec}
+