http://java.net/jira/browse/GLASSFISH-11984 SECTION: Modified Files ---------------------------- M jsf-ri/test/com/sun/faces/renderkit/TestRenderKit.java M jsf-ri/test/com/sun/faces/config/ConfigureListenerTestCase.java Modified the above 2 tests to remove not just ApplicationAssociate but the corresponding ApplicationImpl instance from the servletContext These 2 instance go hand in hand. M jsf-ri/src/main/java/com/sun/faces/application/ApplicationAssociate.java Made the string ASSOCIATE_KEY public. Also added code for cases where there is no Application instance, but there is an ApplicationWrapper instance M jsf-ri/src/main/java/com/sun/faces/application/ApplicationFactoryImpl.java Modified the getApplication() and setApplication() such that it does not store the "application" instance anymore. M jsf-ri/src/main/java/com/sun/faces/application/ApplicationImpl.java added a method to access the ApplicationAssociate instance and 2 methods to clear this entry from the ServletContext/ExternalContext M jsf-ri/src/main/java/com/sun/faces/application/InjectionApplicationFactory.java Modified it to not store an "application" instance. M jsf-ri/src/main/java/com/sun/faces/config/ConfigureListener.java added a line to remove the Application instance SECTION: Diffs ---------------------------- Index: jsf-ri/test/com/sun/faces/renderkit/TestRenderKit.java =================================================================== --- jsf-ri/test/com/sun/faces/renderkit/TestRenderKit.java (revision 8758) +++ jsf-ri/test/com/sun/faces/renderkit/TestRenderKit.java (working copy) @@ -470,6 +470,7 @@ ServletContext servletContext = (ServletContext) ctx.getExternalContext().getContext(); FactoryFinder.releaseFactories(); servletContext.removeAttribute("com.sun.faces.ApplicationAssociate"); + servletContext.removeAttribute("com.sun.faces.application.ApplicationImpl"); ConfigManager config = ConfigManager.getInstance(); DocumentBuilderFactory factory = DbfFactory.getFactory(); Index: jsf-ri/test/com/sun/faces/config/ConfigureListenerTestCase.java =================================================================== --- jsf-ri/test/com/sun/faces/config/ConfigureListenerTestCase.java (revision 8758) +++ jsf-ri/test/com/sun/faces/config/ConfigureListenerTestCase.java (working copy) @@ -133,6 +133,7 @@ import com.sun.faces.cactus.ServletFacesTestCase; import com.sun.faces.config.WebConfiguration.BooleanWebContextInitParameter; import com.sun.faces.application.ApplicationAssociate; +import com.sun.faces.application.ApplicationImpl; import junit.framework.Test; import junit.framework.TestSuite; @@ -254,6 +255,7 @@ ServletContext ctx = (ServletContext) getFacesContext().getExternalContext().getContext(); ApplicationAssociate.clearInstance(getFacesContext().getExternalContext()); + ApplicationImpl.clearInstance(getFacesContext().getExternalContext()); ctx.removeAttribute("com.sun.faces.config.WebConfiguration"); ServletContextWrapper w = new ServletContextWrapper(ctx); ServletContextEvent sce = new ServletContextEvent(w); @@ -297,6 +299,7 @@ ServletContext ctx = (ServletContext) getFacesContext().getExternalContext().getContext(); ApplicationAssociate.clearInstance(getFacesContext().getExternalContext()); + ApplicationImpl.clearInstance(getFacesContext().getExternalContext()); ctx.removeAttribute("com.sun.faces.config.WebConfiguration"); ServletContextWrapper w = new ServletContextWrapper(ctx); ServletContextEvent sce = new ServletContextEvent(w); Index: jsf-ri/src/main/java/com/sun/faces/application/ApplicationAssociate.java =================================================================== --- jsf-ri/src/main/java/com/sun/faces/application/ApplicationAssociate.java (revision 8758) +++ jsf-ri/src/main/java/com/sun/faces/application/ApplicationAssociate.java (working copy) @@ -91,6 +91,9 @@ import javax.faces.application.ProjectStage; import javax.faces.event.PreDestroyCustomScopeEvent; import javax.faces.event.ScopeContext; +import javax.faces.application.ApplicationWrapper; +import javax.faces.application.ApplicationFactory; +import javax.faces.application.Application; import javax.servlet.ServletContext; import java.util.Collections; @@ -138,7 +141,7 @@ // Flag indicating that a response has been rendered. private boolean responseRendered = false; - private static final String ASSOCIATE_KEY = RIConstants.FACES_PREFIX + + public static final String ASSOCIATE_KEY = RIConstants.FACES_PREFIX + "ApplicationAssociate"; private static ThreadLocal instance = @@ -244,15 +247,50 @@ return null; } Map applicationMap = externalContext.getApplicationMap(); - return ((ApplicationAssociate) + ApplicationAssociate appAssociate = ((ApplicationAssociate) applicationMap.get(ASSOCIATE_KEY)); + if (appAssociate == null) { + ApplicationFactory afactory = (ApplicationFactory) + FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY); + Application app = afactory.getApplication(); + if (app != null) { + if (app instanceof ApplicationWrapper) { + appAssociate = ((ApplicationImpl)(((ApplicationWrapper)app).getWrapped())).getApplicationAssociate(); + externalContext.getApplicationMap().put(ASSOCIATE_KEY, appAssociate); + } else { + if (app instanceof ApplicationImpl) { + appAssociate = ((ApplicationImpl)app).getApplicationAssociate(); + externalContext.getApplicationMap().put(ASSOCIATE_KEY, appAssociate); + } + } + } + } + return appAssociate; } public static ApplicationAssociate getInstance(ServletContext context) { if (context == null) { return null; } - return (ApplicationAssociate) context.getAttribute(ASSOCIATE_KEY); + ApplicationAssociate appAssociate = + (ApplicationAssociate) context.getAttribute(ASSOCIATE_KEY); + if (appAssociate == null) { + ApplicationFactory afactory = (ApplicationFactory) + FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY); + Application app = afactory.getApplication(); + if (app != null) { + if (app instanceof ApplicationWrapper) { + appAssociate = ((ApplicationImpl)(((ApplicationWrapper)app).getWrapped())).getApplicationAssociate(); + context.setAttribute(ASSOCIATE_KEY, appAssociate); + } else { + if (app instanceof ApplicationImpl) { + appAssociate = ((ApplicationImpl)app).getApplicationAssociate(); + context.setAttribute(ASSOCIATE_KEY, appAssociate); + } + } + } + } + return appAssociate; } public static void setCurrentInstance(ApplicationAssociate associate) { Index: jsf-ri/src/main/java/com/sun/faces/application/ApplicationFactoryImpl.java =================================================================== --- jsf-ri/src/main/java/com/sun/faces/application/ApplicationFactoryImpl.java (revision 8758) +++ jsf-ri/src/main/java/com/sun/faces/application/ApplicationFactoryImpl.java (working copy) @@ -49,6 +49,7 @@ import javax.faces.application.Application; import javax.faces.application.ApplicationFactory; +import javax.faces.context.FacesContext; /** *

ApplicationFactory is a factory object that creates @@ -66,31 +67,12 @@ // Log instance for this class private static final Logger logger = FacesLogger.APPLICATION.getLogger(); - // - // Protected Constants - // - // - // Class Variables - // - - // Attribute Instance Variables - - private volatile Application application; - - // Relationship Instance Variables - - // - // Constructors and Initializers - // - - /* * Constructor */ public ApplicationFactoryImpl() { super(); - application = null; if (logger.isLoggable(Level.FINE)) { logger.log(Level.FINE, "Created ApplicationFactory "); } @@ -102,7 +84,8 @@ * for this web application.

*/ public Application getApplication() { - + Application application = + (Application)FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().get(ApplicationImpl.class.getName()); if (application == null) { application = new ApplicationImpl(); if (logger.isLoggable(Level.FINE)) { @@ -113,7 +96,7 @@ return application; } - + /** *

Replace the {@link Application} instance that will be * returned for this web application.

@@ -127,7 +110,9 @@ throw new NullPointerException(message); } - this.application = application; + FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().put(ApplicationImpl.class.getName(), application); + FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().put(ApplicationAssociate.ASSOCIATE_KEY, + ((com.sun.faces.application.ApplicationImpl)application).getApplicationAssociate()); if (logger.isLoggable(Level.FINE)) { logger.fine(MessageFormat.format("set Application Instance to ''{0}''", application.getClass().getName())); Index: jsf-ri/src/main/java/com/sun/faces/application/ApplicationImpl.java =================================================================== --- jsf-ri/src/main/java/com/sun/faces/application/ApplicationImpl.java (revision 8758) +++ jsf-ri/src/main/java/com/sun/faces/application/ApplicationImpl.java (working copy) @@ -40,6 +40,7 @@ package com.sun.faces.application; +import javax.servlet.ServletContext; import java.beans.PropertyEditor; import java.beans.PropertyEditorManager; import java.lang.reflect.Constructor; @@ -76,6 +77,7 @@ import javax.faces.component.UIViewRoot; import javax.faces.component.behavior.Behavior; import javax.faces.context.FacesContext; +import javax.faces.context.ExternalContext; import javax.faces.convert.Converter; import javax.faces.convert.DateTimeConverter; import javax.faces.el.MethodBinding; @@ -234,7 +236,23 @@ } } + /** + * method to return the ApplicationAssociate instance + * @return associate + */ + public ApplicationAssociate getApplicationAssociate() { + return associate; + } + public static void clearInstance(ServletContext sc) { + sc.removeAttribute(ApplicationImpl.class.getName()); + } + + public static void clearInstance(ExternalContext sc) { + sc.getApplicationMap().remove(ApplicationImpl.class.getName()); + } + + /** * @see javax.faces.application.Application#publishEvent(FacesContext, Class, Object) */ Index: jsf-ri/src/main/java/com/sun/faces/application/InjectionApplicationFactory.java =================================================================== --- jsf-ri/src/main/java/com/sun/faces/application/InjectionApplicationFactory.java (revision 8758) +++ jsf-ri/src/main/java/com/sun/faces/application/InjectionApplicationFactory.java (working copy) @@ -65,11 +65,7 @@ private static final Logger LOGGER = FacesLogger.APPLICATION.getLogger(); private ApplicationFactory delegate; - private Application defaultApplication; - private Field defaultApplicationField; - private volatile Application application; - - + // ------------------------------------------------------------ Constructors @@ -85,18 +81,17 @@ public Application getApplication() { - + + Application application = delegate.getApplication(); if (application == null) { - application = delegate.getApplication(); - if (application == null) { - // No i18n here + // No i18n here String message = MessageFormat .format("Delegate ApplicationContextFactory, {0}, returned null when calling getApplication().", - delegate.getClass().getName()); - throw new IllegalStateException(message); - } - injectDefaultApplication(); + delegate.getClass().getName()); + throw new IllegalStateException(message); } + injectDefaultApplication(application); + return application; } @@ -104,9 +99,8 @@ public synchronized void setApplication(Application application) { - this.application = application; delegate.setApplication(application); - injectDefaultApplication(); + injectDefaultApplication(application); } @@ -125,25 +119,19 @@ // --------------------------------------------------------- Private Methods - private void injectDefaultApplication() { + private void injectDefaultApplication(Application application) { + Application defaultApplication; + Field defaultApplicationField; + FacesContext ctx = FacesContext.getCurrentInstance(); + String attrName = ApplicationImpl.class.getName(); + defaultApplication = (Application) ctx.getExternalContext().getApplicationMap().get(attrName); - if (defaultApplication == null) { - FacesContext ctx = FacesContext.getCurrentInstance(); - String attrName = ApplicationImpl.class.getName(); - defaultApplication = (Application) ctx.getExternalContext() - .getApplicationMap().get(attrName); - ctx.getExternalContext().getApplicationMap() - .remove(attrName); - } if (defaultApplication != null) { try { - if (defaultApplicationField == null) { - defaultApplicationField = - Application.class - .getDeclaredField("defaultApplication"); - defaultApplicationField.setAccessible(true); - } + defaultApplicationField = + Application.class.getDeclaredField("defaultApplication"); + defaultApplicationField.setAccessible(true); defaultApplicationField.set(application, defaultApplication); } catch (NoSuchFieldException nsfe) { Index: jsf-ri/src/main/java/com/sun/faces/config/ConfigureListener.java =================================================================== --- jsf-ri/src/main/java/com/sun/faces/config/ConfigureListener.java (revision 8758) +++ jsf-ri/src/main/java/com/sun/faces/config/ConfigureListener.java (working copy) @@ -344,6 +344,7 @@ } finally { ApplicationAssociate.clearInstance(context); ApplicationAssociate.setCurrentInstance(null); + com.sun.faces.application.ApplicationImpl.clearInstance(context); // Release the initialization mark on this web application ConfigManager.getInstance().destory(context); if (initContext != null) {