You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by xu...@apache.org on 2011/09/16 10:46:53 UTC
svn commit: r1171450 - in /geronimo/server/trunk/plugins:
j2ee/geronimo-web/src/main/java/org/apache/geronimo/web/
jetty8/geronimo-jetty8/src/main/java/org/apache/geronimo/jetty8/
jetty8/geronimo-jetty8/src/main/java/org/apache/geronimo/jetty8/handler/...
Author: xuhaihong
Date: Fri Sep 16 08:46:53 2011
New Revision: 1171450
URL: http://svn.apache.org/viewvc?rev=1171450&view=rev
Log:
GERONIMO-6145 Factory info should not be shared among those web jsf applications in one EAR package
Added:
geronimo/server/trunk/plugins/j2ee/geronimo-web/src/main/java/org/apache/geronimo/web/WebApplicationIdentity.java
geronimo/server/trunk/plugins/myfaces/geronimo-myfaces/src/main/java/org/apache/geronimo/myfaces/GeronimoFactoryFinderProvider.java
geronimo/server/trunk/plugins/myfaces/geronimo-myfaces/src/main/java/org/apache/geronimo/myfaces/GeronimoFactoryFinderProviderFactory.java
geronimo/server/trunk/plugins/myfaces/geronimo-myfaces/src/main/java/org/apache/geronimo/myfaces/MyFacesSystemInitializer.java
geronimo/server/trunk/plugins/tomcat/geronimo-tomcat7/src/main/java/org/apache/geronimo/tomcat/interceptor/WebApplicationIdentityBeforeAfter.java
Modified:
geronimo/server/trunk/plugins/jetty8/geronimo-jetty8/src/main/java/org/apache/geronimo/jetty8/WebAppContextWrapper.java
geronimo/server/trunk/plugins/jetty8/geronimo-jetty8/src/main/java/org/apache/geronimo/jetty8/handler/GeronimoWebAppContext.java
geronimo/server/trunk/plugins/jetty8/geronimo-jetty8/src/main/java/org/apache/geronimo/jetty8/handler/IntegrationContext.java
geronimo/server/trunk/plugins/jetty8/geronimo-jetty8/src/test/java/org/apache/geronimo/jetty8/AbstractWebModuleTest.java
geronimo/server/trunk/plugins/myfaces/myfaces/src/main/plan/plan.xml
geronimo/server/trunk/plugins/tomcat/geronimo-tomcat7/src/main/java/org/apache/geronimo/tomcat/GeronimoStandardContext.java
geronimo/server/trunk/plugins/tomcat/geronimo-tomcat7/src/main/java/org/apache/geronimo/tomcat/TomcatContext.java
Added: geronimo/server/trunk/plugins/j2ee/geronimo-web/src/main/java/org/apache/geronimo/web/WebApplicationIdentity.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/j2ee/geronimo-web/src/main/java/org/apache/geronimo/web/WebApplicationIdentity.java?rev=1171450&view=auto
==============================================================================
--- geronimo/server/trunk/plugins/j2ee/geronimo-web/src/main/java/org/apache/geronimo/web/WebApplicationIdentity.java (added)
+++ geronimo/server/trunk/plugins/j2ee/geronimo-web/src/main/java/org/apache/geronimo/web/WebApplicationIdentity.java Fri Sep 16 08:46:53 2011
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.web;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class WebApplicationIdentity {
+
+ private static ThreadLocal<String> IDENTITY = new ThreadLocal<String>();
+
+ public static void setIdentity(String identity) {
+ IDENTITY.set(identity);
+ }
+
+ public static String getIdentity() {
+ return IDENTITY.get();
+ }
+}
Modified: geronimo/server/trunk/plugins/jetty8/geronimo-jetty8/src/main/java/org/apache/geronimo/jetty8/WebAppContextWrapper.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/jetty8/geronimo-jetty8/src/main/java/org/apache/geronimo/jetty8/WebAppContextWrapper.java?rev=1171450&r1=1171449&r2=1171450&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/jetty8/geronimo-jetty8/src/main/java/org/apache/geronimo/jetty8/WebAppContextWrapper.java (original)
+++ geronimo/server/trunk/plugins/jetty8/geronimo-jetty8/src/main/java/org/apache/geronimo/jetty8/WebAppContextWrapper.java Fri Sep 16 08:46:53 2011
@@ -17,8 +17,6 @@
package org.apache.geronimo.jetty8;
-import java.beans.beancontext.BeanContext;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
@@ -36,6 +34,7 @@ import javax.transaction.TransactionMana
import javax.transaction.UserTransaction;
import org.apache.geronimo.connector.outbound.connectiontracking.TrackedConnectionAssociator;
+import org.apache.geronimo.gbean.AbstractName;
import org.apache.geronimo.gbean.GBeanLifecycle;
import org.apache.geronimo.gbean.annotation.GBean;
import org.apache.geronimo.gbean.annotation.ParamAttribute;
@@ -105,6 +104,7 @@ public class WebAppContextWrapper implem
public WebAppContextWrapper(@ParamSpecial(type = SpecialAttributeType.objectName) String objectName,
+ @ParamSpecial(type = SpecialAttributeType.abstractName) AbstractName abName,
@ParamAttribute(name = "contextPath") String contextPath,
@ParamAttribute(name = "deploymentDescriptor") String originalSpecDD,
@ParamAttribute(name = "modulePath") String modulePath,
@@ -222,7 +222,7 @@ public class WebAppContextWrapper implem
}
}
- IntegrationContext integrationContext = new IntegrationContext(componentContext, unshareableResources, applicationManagedSecurityResources, trackedConnectionAssociator, userTransaction, bundle, holder, servletContainerInitializerMap);
+ IntegrationContext integrationContext = new IntegrationContext(componentContext, unshareableResources, applicationManagedSecurityResources, trackedConnectionAssociator, userTransaction, bundle, holder, servletContainerInitializerMap, abName.toString());
webAppContext = new GeronimoWebAppContext(securityHandler, sessionHandler, servletHandler, null, integrationContext, classLoader, modulePath, webAppInfo, policyContextID, applicationPolicyConfigurationManager);
webAppContext.setContextPath(contextPath);
//See Jetty-386. Setting this to true can expose secured content.
Modified: geronimo/server/trunk/plugins/jetty8/geronimo-jetty8/src/main/java/org/apache/geronimo/jetty8/handler/GeronimoWebAppContext.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/jetty8/geronimo-jetty8/src/main/java/org/apache/geronimo/jetty8/handler/GeronimoWebAppContext.java?rev=1171450&r1=1171449&r2=1171450&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/jetty8/geronimo-jetty8/src/main/java/org/apache/geronimo/jetty8/handler/GeronimoWebAppContext.java (original)
+++ geronimo/server/trunk/plugins/jetty8/geronimo-jetty8/src/main/java/org/apache/geronimo/jetty8/handler/GeronimoWebAppContext.java Fri Sep 16 08:46:53 2011
@@ -50,6 +50,7 @@ import org.apache.geronimo.osgi.web.WebA
import org.apache.geronimo.security.jacc.ApplicationPolicyConfigurationManager;
import org.apache.geronimo.security.jacc.ComponentPermissions;
import org.apache.geronimo.web.WebApplicationConstants;
+import org.apache.geronimo.web.WebApplicationIdentity;
import org.apache.geronimo.web.assembler.Assembler;
import org.apache.geronimo.web.info.WebAppInfo;
import org.apache.geronimo.web.security.SpecSecurityBuilder;
@@ -232,6 +233,8 @@ public class GeronimoWebAppContext exten
SharedConnectorInstanceContext newContext = integrationContext.newConnectorInstanceContext(baseRequest);
ConnectorInstanceContext connectorContext = integrationContext.setConnectorInstance(baseRequest, newContext);
WebBeansContext owbContext = integrationContext.contextEntered();
+ String oldApplicationIdentity = WebApplicationIdentity.getIdentity();
+ WebApplicationIdentity.setIdentity(integrationContext.getWebApplicationIdentity());
try {
try {
super.doScope(target, baseRequest, request, response);
@@ -242,6 +245,7 @@ public class GeronimoWebAppContext exten
integrationContext.contextExited(owbContext);
integrationContext.restoreContext(context);
integrationContext.completeTx(txActive, baseRequest);
+ WebApplicationIdentity.setIdentity(oldApplicationIdentity);
}
}
Modified: geronimo/server/trunk/plugins/jetty8/geronimo-jetty8/src/main/java/org/apache/geronimo/jetty8/handler/IntegrationContext.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/jetty8/geronimo-jetty8/src/main/java/org/apache/geronimo/jetty8/handler/IntegrationContext.java?rev=1171450&r1=1171449&r2=1171450&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/jetty8/geronimo-jetty8/src/main/java/org/apache/geronimo/jetty8/handler/IntegrationContext.java (original)
+++ geronimo/server/trunk/plugins/jetty8/geronimo-jetty8/src/main/java/org/apache/geronimo/jetty8/handler/IntegrationContext.java Fri Sep 16 08:46:53 2011
@@ -21,7 +21,6 @@
package org.apache.geronimo.jetty8.handler;
import java.util.Collections;
-import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@@ -56,9 +55,10 @@ public class IntegrationContext {
private final Bundle bundle;
private final Holder holder;
private final Map<ServletContainerInitializer, Set<Class<?>>> servletContainerInitializerMap;
+ private final String webApplicationIdentity;
private WebBeansContext owbContext;
- public IntegrationContext(Context componentContext, Set<String> unshareableResources, Set<String> applicationManagedSecurityResources, TrackedConnectionAssociator trackedConnectionAssociator, UserTransaction userTransaction, Bundle bundle, Holder holder, Map<ServletContainerInitializer, Set<Class<?>>> servletContainerInitializerMap) {
+ public IntegrationContext(Context componentContext, Set<String> unshareableResources, Set<String> applicationManagedSecurityResources, TrackedConnectionAssociator trackedConnectionAssociator, UserTransaction userTransaction, Bundle bundle, Holder holder, Map<ServletContainerInitializer, Set<Class<?>>> servletContainerInitializerMap, String webApplicationIdentity) {
this.componentContext = componentContext;
this.unshareableResources = unshareableResources;
this.applicationManagedSecurityResources = applicationManagedSecurityResources;
@@ -67,6 +67,7 @@ public class IntegrationContext {
this.bundle = bundle;
this.holder = holder;
this.servletContainerInitializerMap = servletContainerInitializerMap == null? Collections.<ServletContainerInitializer, Set<Class<?>>>emptyMap(): servletContainerInitializerMap;
+ this.webApplicationIdentity = webApplicationIdentity;
}
public Context getComponentContext() {
@@ -97,6 +98,10 @@ public class IntegrationContext {
return holder;
}
+ public String getWebApplicationIdentity(){
+ return webApplicationIdentity;
+ }
+
public SharedConnectorInstanceContext newConnectorInstanceContext(Request baseRequest) {
return new SharedConnectorInstanceContext(getUnshareableResources(),
getApplicationManagedSecurityResources(),
Modified: geronimo/server/trunk/plugins/jetty8/geronimo-jetty8/src/test/java/org/apache/geronimo/jetty8/AbstractWebModuleTest.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/jetty8/geronimo-jetty8/src/test/java/org/apache/geronimo/jetty8/AbstractWebModuleTest.java?rev=1171450&r1=1171449&r2=1171450&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/jetty8/geronimo-jetty8/src/test/java/org/apache/geronimo/jetty8/AbstractWebModuleTest.java (original)
+++ geronimo/server/trunk/plugins/jetty8/geronimo-jetty8/src/test/java/org/apache/geronimo/jetty8/AbstractWebModuleTest.java Fri Sep 16 08:46:53 2011
@@ -17,6 +17,7 @@
package org.apache.geronimo.jetty8;
import java.io.File;
+import java.net.URI;
import java.net.URL;
import java.security.AccessControlContext;
import java.security.PermissionCollection;
@@ -39,6 +40,7 @@ import javax.transaction.TransactionMana
import org.apache.geronimo.connector.outbound.connectiontracking.ConnectionTrackingCoordinator;
import org.apache.geronimo.connector.outbound.connectiontracking.GeronimoTransactionListener;
+import org.apache.geronimo.gbean.AbstractName;
import org.apache.geronimo.j2ee.annotation.Holder;
import org.apache.geronimo.j2ee.jndi.ContextSource;
import org.apache.geronimo.j2ee.jndi.WebContextSource;
@@ -159,6 +161,7 @@ public class AbstractWebModuleTest exten
null,
null);
WebAppContextWrapper app = new WebAppContextWrapper("geronimo:J2EEServer=geronimo,name=hello.war,J2EEApplication=null,j2eeType=WebModule",
+ new AbstractName(new URI("default/test/1.0/war?J2EEApplication=null,j2eeType=WebModule,name=default/test/1.0/war")),
contextPath,
null,
null,
Added: geronimo/server/trunk/plugins/myfaces/geronimo-myfaces/src/main/java/org/apache/geronimo/myfaces/GeronimoFactoryFinderProvider.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/myfaces/geronimo-myfaces/src/main/java/org/apache/geronimo/myfaces/GeronimoFactoryFinderProvider.java?rev=1171450&view=auto
==============================================================================
--- geronimo/server/trunk/plugins/myfaces/geronimo-myfaces/src/main/java/org/apache/geronimo/myfaces/GeronimoFactoryFinderProvider.java (added)
+++ geronimo/server/trunk/plugins/myfaces/geronimo-myfaces/src/main/java/org/apache/geronimo/myfaces/GeronimoFactoryFinderProvider.java Fri Sep 16 08:46:53 2011
@@ -0,0 +1,346 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.myfaces;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.security.AccessController;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.faces.FacesException;
+import javax.faces.FactoryFinder;
+import javax.faces.application.ApplicationFactory;
+import javax.faces.component.visit.VisitContextFactory;
+import javax.faces.context.ExceptionHandlerFactory;
+import javax.faces.context.ExternalContextFactory;
+import javax.faces.context.FacesContextFactory;
+import javax.faces.context.PartialViewContextFactory;
+import javax.faces.lifecycle.LifecycleFactory;
+import javax.faces.render.RenderKitFactory;
+import javax.faces.view.ViewDeclarationLanguageFactory;
+import javax.faces.view.facelets.TagHandlerDelegateFactory;
+
+import org.apache.geronimo.web.WebApplicationIdentity;
+import org.apache.myfaces.spi.FactoryFinderProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * GeronimoFactoryFinderProvider is forked from javax.faces.FactoryFinder in MyFaces package, including the changes below :
+ * a. Use WebApplicationIdentity as key to hold different map for each web application
+ * b. Remove the codes of FactoryFinderProviderFactory
+ * @version $Rev$ $Date$
+ */
+
+public class GeronimoFactoryFinderProvider implements FactoryFinderProvider {
+
+ private static final Logger logger = LoggerFactory.getLogger(GeronimoFactoryFinderProvider.class);
+
+ public static final String APPLICATION_FACTORY = "javax.faces.application.ApplicationFactory";
+
+ public static final String EXCEPTION_HANDLER_FACTORY = "javax.faces.context.ExceptionHandlerFactory";
+
+ public static final String EXTERNAL_CONTEXT_FACTORY = "javax.faces.context.ExternalContextFactory";
+
+ public static final String FACES_CONTEXT_FACTORY = "javax.faces.context.FacesContextFactory";
+
+ public static final String LIFECYCLE_FACTORY = "javax.faces.lifecycle.LifecycleFactory";
+
+ public static final String PARTIAL_VIEW_CONTEXT_FACTORY = "javax.faces.context.PartialViewContextFactory";
+
+ public static final String RENDER_KIT_FACTORY = "javax.faces.render.RenderKitFactory";
+
+ public static final String TAG_HANDLER_DELEGATE_FACTORY = "javax.faces.view.facelets.TagHandlerDelegateFactory";
+
+ public static final String VIEW_DECLARATION_LANGUAGE_FACTORY = "javax.faces.view.ViewDeclarationLanguageFactory";
+
+ public static final String VISIT_CONTEXT_FACTORY = "javax.faces.component.visit.VisitContextFactory";
+
+ /**
+ * used as a monitor for itself and _factories. Maps in this map are used as monitors for themselves and the
+ * corresponding maps in _factories.
+ */
+ private Map<String, Map<String, List<String>>> _registeredFactoryNames = new HashMap<String, Map<String, List<String>>>();
+
+ private Map<String, Map<String, Object>> _factories = new HashMap<String, Map<String, Object>>();
+
+ private static final Set<String> VALID_FACTORY_NAMES = new HashSet<String>();
+
+ private static final Map<String, Class<?>> ABSTRACT_FACTORY_CLASSES = new HashMap<String, Class<?>>();
+
+ private static final ClassLoader myFacesClassLoader;
+
+ static {
+ VALID_FACTORY_NAMES.add(APPLICATION_FACTORY);
+ VALID_FACTORY_NAMES.add(EXCEPTION_HANDLER_FACTORY);
+ VALID_FACTORY_NAMES.add(EXTERNAL_CONTEXT_FACTORY);
+ VALID_FACTORY_NAMES.add(FACES_CONTEXT_FACTORY);
+ VALID_FACTORY_NAMES.add(LIFECYCLE_FACTORY);
+ VALID_FACTORY_NAMES.add(PARTIAL_VIEW_CONTEXT_FACTORY);
+ VALID_FACTORY_NAMES.add(RENDER_KIT_FACTORY);
+ VALID_FACTORY_NAMES.add(TAG_HANDLER_DELEGATE_FACTORY);
+ VALID_FACTORY_NAMES.add(VIEW_DECLARATION_LANGUAGE_FACTORY);
+ VALID_FACTORY_NAMES.add(VISIT_CONTEXT_FACTORY);
+
+ ABSTRACT_FACTORY_CLASSES.put(APPLICATION_FACTORY, ApplicationFactory.class);
+ ABSTRACT_FACTORY_CLASSES.put(EXCEPTION_HANDLER_FACTORY, ExceptionHandlerFactory.class);
+ ABSTRACT_FACTORY_CLASSES.put(EXTERNAL_CONTEXT_FACTORY, ExternalContextFactory.class);
+ ABSTRACT_FACTORY_CLASSES.put(FACES_CONTEXT_FACTORY, FacesContextFactory.class);
+ ABSTRACT_FACTORY_CLASSES.put(LIFECYCLE_FACTORY, LifecycleFactory.class);
+ ABSTRACT_FACTORY_CLASSES.put(PARTIAL_VIEW_CONTEXT_FACTORY, PartialViewContextFactory.class);
+ ABSTRACT_FACTORY_CLASSES.put(RENDER_KIT_FACTORY, RenderKitFactory.class);
+ ABSTRACT_FACTORY_CLASSES.put(TAG_HANDLER_DELEGATE_FACTORY, TagHandlerDelegateFactory.class);
+ ABSTRACT_FACTORY_CLASSES.put(VIEW_DECLARATION_LANGUAGE_FACTORY, ViewDeclarationLanguageFactory.class);
+ ABSTRACT_FACTORY_CLASSES.put(VISIT_CONTEXT_FACTORY, VisitContextFactory.class);
+ try {
+ ClassLoader classLoader;
+ if (System.getSecurityManager() != null) {
+ classLoader = (ClassLoader) AccessController.doPrivileged(new java.security.PrivilegedExceptionAction() {
+
+ public Object run() {
+ return FactoryFinder.class.getClassLoader();
+ }
+ });
+ } else {
+ classLoader = FactoryFinder.class.getClassLoader();
+ }
+
+ if (classLoader == null) {
+ throw new FacesException("jsf api class loader cannot be identified", null);
+ }
+ myFacesClassLoader = classLoader;
+ } catch (Exception e) {
+ throw new FacesException("jsf api class loader cannot be identified", e);
+ }
+ }
+
+ public Object getFactory(String factoryName) throws FacesException {
+ if (factoryName == null) {
+ throw new NullPointerException("factoryName may not be null");
+ }
+
+ ClassLoader classLoader = getClassLoader();
+
+ // This code must be synchronized because this could cause a problem when
+ // using update feature each time of myfaces (org.apache.myfaces.CONFIG_REFRESH_PERIOD)
+ // In this moment, a concurrency problem could happen
+ Map<String, List<String>> factoryClassNames = null;
+ Map<String, Object> factoryMap = null;
+
+ String webApplicationIdentity = WebApplicationIdentity.getIdentity();
+ if(webApplicationIdentity == null) {
+ throw new IllegalStateException("No web identity is attached to current request thread " + Thread.currentThread().getName());
+ }
+
+ synchronized (_registeredFactoryNames) {
+ factoryClassNames = _registeredFactoryNames.get(webApplicationIdentity);
+
+ if (factoryClassNames == null) {
+ String message = "No Factories configured for this Application. This happens if the faces-initialization "
+ + "does not work at all - make sure that you properly include all configuration settings necessary for a basic faces application "
+ + "and that all the necessary libs are included. Also check the logging output of your web application and your container for any exceptions!"
+ + "\nIf you did that and find nothing, the mistake might be due to the fact that you use some special web-containers which "
+ + "do not support registering context-listeners via TLD files and " + "a context listener is not setup in your web.xml.\n" + "A typical config looks like this;\n<listener>\n"
+ + " <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>\n" + "</listener>\n";
+ throw new IllegalStateException(message);
+ }
+
+ if (!factoryClassNames.containsKey(factoryName)) {
+ throw new IllegalArgumentException("no factory " + factoryName + " configured for this application.");
+ }
+
+ factoryMap = _factories.get(classLoader);
+
+ if (factoryMap == null) {
+ factoryMap = new HashMap<String, Object>();
+ _factories.put(webApplicationIdentity, factoryMap);
+ }
+ }
+
+ List<String> classNames;
+ Object factory;
+ synchronized (factoryClassNames) {
+ factory = factoryMap.get(factoryName);
+ if (factory != null) {
+ return factory;
+ }
+
+ classNames = factoryClassNames.get(factoryName);
+ }
+
+ // release lock while calling out
+ factory = newFactoryInstance(ABSTRACT_FACTORY_CLASSES.get(factoryName), classNames.iterator(), classLoader);
+
+ synchronized (factoryClassNames) {
+ // check if someone else already installed the factory
+ if (factoryMap.get(factoryName) == null) {
+ factoryMap.put(factoryName, factory);
+ }
+ }
+
+ return factory;
+ }
+
+ private Object newFactoryInstance(Class<?> interfaceClass, Iterator<String> classNamesIterator, ClassLoader classLoader) {
+ try {
+ Object current = null;
+
+ while (classNamesIterator.hasNext()) {
+ String implClassName = classNamesIterator.next();
+ Class<?> implClass = null;
+ try {
+ implClass = classLoader.loadClass(implClassName);
+ } catch (ClassNotFoundException e) {
+ implClass = myFacesClassLoader.loadClass(implClassName);
+ }
+
+ // check, if class is of expected interface type
+ if (!interfaceClass.isAssignableFrom(implClass)) {
+ throw new IllegalArgumentException("Class " + implClassName + " is no " + interfaceClass.getName());
+ }
+
+ if (current == null) {
+ // nothing to decorate
+ current = implClass.newInstance();
+ } else {
+ // let's check if class supports the decorator pattern
+ try {
+ Constructor<?> delegationConstructor = implClass.getConstructor(new Class[] { interfaceClass });
+ // impl class supports decorator pattern,
+ try {
+ // create new decorator wrapping current
+ current = delegationConstructor.newInstance(new Object[] { current });
+ } catch (InstantiationException e) {
+ throw new FacesException(e);
+ } catch (IllegalAccessException e) {
+ throw new FacesException(e);
+ } catch (InvocationTargetException e) {
+ throw new FacesException(e);
+ }
+ } catch (NoSuchMethodException e) {
+ // no decorator pattern support
+ current = implClass.newInstance();
+ }
+ }
+ }
+ return current;
+ } catch (ClassNotFoundException e) {
+ throw new FacesException(e);
+ } catch (InstantiationException e) {
+ throw new FacesException(e);
+ } catch (IllegalAccessException e) {
+ throw new FacesException(e);
+ }
+ }
+
+ public void setFactory(String factoryName, String implName) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Enter setFactory " + factoryName + " = " + implName);
+ }
+ checkFactoryName(factoryName);
+
+ String webApplicationIdentity = WebApplicationIdentity.getIdentity();
+ if(webApplicationIdentity == null) {
+ throw new IllegalStateException("No web identity is attached to current request thread " + Thread.currentThread().getName());
+ }
+
+ Map<String, List<String>> factoryClassNames = null;
+ synchronized (_registeredFactoryNames) {
+ Map<String, Object> factories = _factories.get(webApplicationIdentity);
+ if (factories != null && factories.containsKey(factoryName)) {
+ // Javadoc says ... This method has no effect if getFactory() has already been
+ // called looking for a factory for this factoryName.
+ return;
+ }
+ factoryClassNames = _registeredFactoryNames.get(webApplicationIdentity);
+ if (factoryClassNames == null) {
+ factoryClassNames = new HashMap<String, List<String>>();
+ _registeredFactoryNames.put(webApplicationIdentity, factoryClassNames);
+ }
+ }
+ synchronized (factoryClassNames) {
+ List<String> classNameList = factoryClassNames.get(factoryName);
+ if (classNameList == null) {
+ classNameList = new ArrayList<String>();
+ factoryClassNames.put(factoryName, classNameList);
+ }
+ classNameList.add(implName);
+ if (logger.isDebugEnabled()) {
+ logger.debug("Factory map of web application [" + webApplicationIdentity + "] is " + factoryClassNames);
+ }
+ }
+ }
+
+ public void releaseFactories() throws FacesException {
+ String webApplicationIdentity = WebApplicationIdentity.getIdentity();
+ if(webApplicationIdentity == null) {
+ throw new IllegalStateException("No web identity is attached to current request thread " + Thread.currentThread().getName());
+ }
+
+ // This code must be synchronized
+ synchronized (_registeredFactoryNames) {
+ _factories.remove(webApplicationIdentity);
+ // _registeredFactoryNames has as value type Map<String,List> and this must
+ // be cleaned before release (for gc).
+ Map<String, List<String>> factoryClassNames = _registeredFactoryNames.get(webApplicationIdentity);
+ if (factoryClassNames != null) {
+ factoryClassNames.clear();
+ }
+ Map<String, List<String>>factoryMap = _registeredFactoryNames.remove(webApplicationIdentity);
+ if(logger.isDebugEnabled()) {
+ logger.debug("Web application [" + webApplicationIdentity + "] releases the factory map " + factoryMap);
+ }
+ }
+ }
+
+ private void checkFactoryName(String factoryName) {
+ if (!VALID_FACTORY_NAMES.contains(factoryName)) {
+ throw new IllegalArgumentException("factoryName '" + factoryName + "'");
+ }
+ }
+
+ private ClassLoader getClassLoader() {
+ try {
+ ClassLoader classLoader = null;
+ if (System.getSecurityManager() != null) {
+ classLoader = (ClassLoader) AccessController.doPrivileged(new java.security.PrivilegedExceptionAction() {
+
+ public Object run() {
+ return Thread.currentThread().getContextClassLoader();
+ }
+ });
+ } else {
+ classLoader = Thread.currentThread().getContextClassLoader();
+ }
+
+ if (classLoader == null) {
+ throw new FacesException("web application class loader cannot be identified", null);
+ }
+ return classLoader;
+ } catch (Exception e) {
+ throw new FacesException("web application class loader cannot be identified", e);
+ }
+ }
+
+}
Added: geronimo/server/trunk/plugins/myfaces/geronimo-myfaces/src/main/java/org/apache/geronimo/myfaces/GeronimoFactoryFinderProviderFactory.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/myfaces/geronimo-myfaces/src/main/java/org/apache/geronimo/myfaces/GeronimoFactoryFinderProviderFactory.java?rev=1171450&view=auto
==============================================================================
--- geronimo/server/trunk/plugins/myfaces/geronimo-myfaces/src/main/java/org/apache/geronimo/myfaces/GeronimoFactoryFinderProviderFactory.java (added)
+++ geronimo/server/trunk/plugins/myfaces/geronimo-myfaces/src/main/java/org/apache/geronimo/myfaces/GeronimoFactoryFinderProviderFactory.java Fri Sep 16 08:46:53 2011
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.myfaces;
+
+import org.apache.myfaces.spi.FactoryFinderProvider;
+import org.apache.myfaces.spi.FactoryFinderProviderFactory;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class GeronimoFactoryFinderProviderFactory extends FactoryFinderProviderFactory {
+
+ private GeronimoFactoryFinderProvider factoryFinderProvider = new GeronimoFactoryFinderProvider();
+
+ @Override
+ public FactoryFinderProvider getFactoryFinderProvider() {
+ return factoryFinderProvider;
+ }
+
+}
Added: geronimo/server/trunk/plugins/myfaces/geronimo-myfaces/src/main/java/org/apache/geronimo/myfaces/MyFacesSystemInitializer.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/myfaces/geronimo-myfaces/src/main/java/org/apache/geronimo/myfaces/MyFacesSystemInitializer.java?rev=1171450&view=auto
==============================================================================
--- geronimo/server/trunk/plugins/myfaces/geronimo-myfaces/src/main/java/org/apache/geronimo/myfaces/MyFacesSystemInitializer.java (added)
+++ geronimo/server/trunk/plugins/myfaces/geronimo-myfaces/src/main/java/org/apache/geronimo/myfaces/MyFacesSystemInitializer.java Fri Sep 16 08:46:53 2011
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.myfaces;
+
+import org.apache.geronimo.gbean.GBeanLifecycle;
+import org.apache.geronimo.gbean.annotation.GBean;
+import org.apache.myfaces.spi.FactoryFinderProviderFactory;
+
+/**
+ * @version $Rev$ $Date$
+ */
+@GBean
+public class MyFacesSystemInitializer implements GBeanLifecycle {
+
+ @Override
+ public void doFail() {
+ try {
+ doStop();
+ } catch (Exception e) {
+ }
+ }
+
+ @Override
+ public void doStart() throws Exception {
+ FactoryFinderProviderFactory.setInstance(new GeronimoFactoryFinderProviderFactory());
+
+ }
+
+ @Override
+ public void doStop() throws Exception {
+ FactoryFinderProviderFactory.setInstance(null);
+ }
+
+}
Modified: geronimo/server/trunk/plugins/myfaces/myfaces/src/main/plan/plan.xml
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/myfaces/myfaces/src/main/plan/plan.xml?rev=1171450&r1=1171449&r2=1171450&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/myfaces/myfaces/src/main/plan/plan.xml (original)
+++ geronimo/server/trunk/plugins/myfaces/myfaces/src/main/plan/plan.xml Fri Sep 16 08:46:53 2011
@@ -19,5 +19,5 @@
<!-- $Rev$ $Date$ -->
<module xmlns="http://geronimo.apache.org/xml/ns/deployment-${geronimoSchemaVersion}">
-
+ <gbean name="MyFacesSystemInitializer" class="org.apache.geronimo.myfaces.MyFacesSystemInitializer"/>
</module>
Modified: geronimo/server/trunk/plugins/tomcat/geronimo-tomcat7/src/main/java/org/apache/geronimo/tomcat/GeronimoStandardContext.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/tomcat/geronimo-tomcat7/src/main/java/org/apache/geronimo/tomcat/GeronimoStandardContext.java?rev=1171450&r1=1171449&r2=1171450&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/tomcat/geronimo-tomcat7/src/main/java/org/apache/geronimo/tomcat/GeronimoStandardContext.java (original)
+++ geronimo/server/trunk/plugins/tomcat/geronimo-tomcat7/src/main/java/org/apache/geronimo/tomcat/GeronimoStandardContext.java Fri Sep 16 08:46:53 2011
@@ -89,6 +89,7 @@ import org.apache.geronimo.tomcat.interc
import org.apache.geronimo.tomcat.interceptor.OWBBeforeAfter;
import org.apache.geronimo.tomcat.interceptor.PolicyContextBeforeAfter;
import org.apache.geronimo.tomcat.interceptor.UserTransactionBeforeAfter;
+import org.apache.geronimo.tomcat.interceptor.WebApplicationIdentityBeforeAfter;
import org.apache.geronimo.tomcat.listener.DispatchListener;
import org.apache.geronimo.tomcat.listener.RunAsInstanceListener;
import org.apache.geronimo.tomcat.util.SecurityHolder;
@@ -308,6 +309,8 @@ public class GeronimoStandardContext ext
//Set a UserTransactionBeforeAfter
interceptor = new UserTransactionBeforeAfter(interceptor, index++, ctx.getUserTransaction());
+ interceptor = new WebApplicationIdentityBeforeAfter(interceptor, index++, ctx.getAbstractName().toString());
+
addValve(new ProtectedTargetValve());
Valve clusteredValve = ctx.getClusteredValve();
@@ -825,7 +828,7 @@ public class GeronimoStandardContext ext
}
}
}
-
+
private class SystemMethodValve extends ValveBase {
public SystemMethodValve(){
Modified: geronimo/server/trunk/plugins/tomcat/geronimo-tomcat7/src/main/java/org/apache/geronimo/tomcat/TomcatContext.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/tomcat/geronimo-tomcat7/src/main/java/org/apache/geronimo/tomcat/TomcatContext.java?rev=1171450&r1=1171449&r2=1171450&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/tomcat/geronimo-tomcat7/src/main/java/org/apache/geronimo/tomcat/TomcatContext.java (original)
+++ geronimo/server/trunk/plugins/tomcat/geronimo-tomcat7/src/main/java/org/apache/geronimo/tomcat/TomcatContext.java Fri Sep 16 08:46:53 2011
@@ -30,6 +30,7 @@ import org.apache.catalina.Realm;
import org.apache.catalina.Valve;
import org.apache.catalina.ha.CatalinaCluster;
import org.apache.geronimo.connector.outbound.connectiontracking.TrackedConnectionAssociator;
+import org.apache.geronimo.gbean.AbstractName;
import org.apache.geronimo.kernel.Kernel;
import org.apache.geronimo.tomcat.util.SecurityHolder;
import org.apache.geronimo.web.info.WebAppInfo;
@@ -103,4 +104,6 @@ public interface TomcatContext {
Map<String, String> getContextAttributes();
WebBeansContext getOWBContext();
+
+ AbstractName getAbstractName();
}
Added: geronimo/server/trunk/plugins/tomcat/geronimo-tomcat7/src/main/java/org/apache/geronimo/tomcat/interceptor/WebApplicationIdentityBeforeAfter.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/tomcat/geronimo-tomcat7/src/main/java/org/apache/geronimo/tomcat/interceptor/WebApplicationIdentityBeforeAfter.java?rev=1171450&view=auto
==============================================================================
--- geronimo/server/trunk/plugins/tomcat/geronimo-tomcat7/src/main/java/org/apache/geronimo/tomcat/interceptor/WebApplicationIdentityBeforeAfter.java (added)
+++ geronimo/server/trunk/plugins/tomcat/geronimo-tomcat7/src/main/java/org/apache/geronimo/tomcat/interceptor/WebApplicationIdentityBeforeAfter.java Fri Sep 16 08:46:53 2011
@@ -0,0 +1,74 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.tomcat.interceptor;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+import org.apache.geronimo.web.WebApplicationIdentity;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class WebApplicationIdentityBeforeAfter implements BeforeAfter {
+
+ private String identity;
+
+ private int index;
+
+ private BeforeAfter next;
+
+ public WebApplicationIdentityBeforeAfter(BeforeAfter next, int index, String identity) {
+ this.identity = identity;
+ this.index = index;
+ this.next = next;
+ }
+
+ @Override
+ public void before(BeforeAfterContext beforeAfterContext, ServletRequest httpRequest, ServletResponse httpResponse, int dispatch) {
+ try {
+ beforeAfterContext.contexts[index] = WebApplicationIdentity.getIdentity();
+ WebApplicationIdentity.setIdentity(identity);
+ beforeAfterContext.clearRequiredFlags[index] = true;
+ if (next != null) {
+ next.before(beforeAfterContext, httpRequest, httpResponse, dispatch);
+ }
+ } catch (RuntimeException e) {
+ if (beforeAfterContext.clearRequiredFlags[index]) {
+ WebApplicationIdentity.setIdentity((String) beforeAfterContext.contexts[index]);
+ beforeAfterContext.clearRequiredFlags[index] = false;
+ }
+ throw e;
+ }
+ }
+
+ @Override
+ public void after(BeforeAfterContext beforeAfterContext, ServletRequest httpRequest, ServletResponse httpResponse, int dispatch) {
+ try {
+ if (next != null) {
+ next.after(beforeAfterContext, httpRequest, httpResponse, dispatch);
+ }
+ } finally {
+ if (beforeAfterContext.clearRequiredFlags[index]) {
+ WebApplicationIdentity.setIdentity((String) beforeAfterContext.contexts[index]);
+ beforeAfterContext.clearRequiredFlags[index] = false;
+ }
+ }
+ }
+
+}