Skip to content
This repository has been archived by the owner on Apr 8, 2019. It is now read-only.

GTNPORTAL-2895 Support for CDI in portlets and filters #401

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
59 changes: 59 additions & 0 deletions cdi/injection/pom.xml
@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ JBoss, a division of Red Hat
~ Copyright 2013, Red Hat Middleware, LLC, and individual
~ contributors as indicated by the @authors tag. See the
~ copyright.txt in the distribution for a full listing of
~ individual contributors.
~
~ This is free software; you can redistribute it and/or modify it
~ under the terms of the GNU Lesser General Public License as
~ published by the Free Software Foundation; either version 2.1 of
~ the License, or (at your option) any later version.
~
~ This software is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
~ Lesser General Public License for more details.
~
~ You should have received a copy of the GNU Lesser General Public
~ License along with this software; if not, write to the Free
~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.gatein.cdi</groupId>
<artifactId>gatein-cdi-parent</artifactId>
<version>3.6.0.Beta02-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>gatein-cdi-injection</artifactId>
<packaging>jar</packaging>
<name>GateIn CDI Portlet and Filter Injection</name>

<dependencies>
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.portlet</groupId>
<artifactId>portlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gatein.pc</groupId>
<artifactId>pc-portlet</artifactId>
</dependency>
</dependencies>

</project>
223 changes: 223 additions & 0 deletions 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 <a href="http://community.jboss.org/people/kenfinni">Ken Finnigan</a>
*/
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<String, CDIMetaData> cdiMetaDataMap = new ConcurrentHashMap<String, CDIMetaData>();

private List<Class<? extends PortletFilter>> filterClasses = new ArrayList<Class<? extends PortletFilter>>();

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;
}
}
46 changes: 46 additions & 0 deletions cdi/pom.xml
@@ -0,0 +1,46 @@
<!--
~ JBoss, a division of Red Hat
~ Copyright 2013, Red Hat Middleware, LLC, and individual
~ contributors as indicated by the @authors tag. See the
~ copyright.txt in the distribution for a full listing of
~ individual contributors.
~
~ This is free software; you can redistribute it and/or modify it
~ under the terms of the GNU Lesser General Public License as
~ published by the Free Software Foundation; either version 2.1 of
~ the License, or (at your option) any later version.
~
~ This software is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
~ Lesser General Public License for more details.
~
~ You should have received a copy of the GNU Lesser General Public
~ License along with this software; if not, write to the Free
~ Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
~ 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<name>GateIn CDI Enhancements</name>

<groupId>org.gatein.cdi</groupId>
<artifactId>gatein-cdi-parent</artifactId>
<version>3.6.0.Beta02-SNAPSHOT</version>

<packaging>pom</packaging>

<parent>
<groupId>org.gatein.portal</groupId>
<artifactId>exo.portal.parent</artifactId>
<version>3.6.0.Beta02-SNAPSHOT</version>
</parent>

<description>GateIn CDI Enhancements parent</description>

<modules>
<module>injection</module>
</modules>
</project>
12 changes: 9 additions & 3 deletions component/pc/pom.xml
@@ -1,17 +1,17 @@
<!--

Copyright (C) 2009 eXo Platform SAS.

This is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of
the License, or (at your option) any later version.

This software is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this software; if not, write to the Free
Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
Expand All @@ -33,6 +33,12 @@

<dependencies>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gatein.portal</groupId>
<artifactId>exo.portal.component.resources</artifactId>
Expand Down