Index: nbproject/project.xml
===================================================================
--- nbproject/project.xml (revision 8870)
+++ nbproject/project.xml (working copy)
@@ -18,6 +18,10 @@
UTF-8
+
+ /Users/edburns/Documents/chaff/netbeans-hack-links/jsf-api-test
+
+
java
jsf-ri/build/generate
@@ -47,6 +51,22 @@
jsf-ri/test
UTF-8
+
+
+ java
+ /Users/edburns/Documents/chaff/netbeans-hack-links/jsf-api-test
+ UTF-8
+
+
+
+ java
+ /Users/edburns/Documents/JavaEE/workareas/mojarra-dependencies/trinidad-assembly-2.0.0-beta-1/src/trinidad-api-2.0.0-beta-1-sources
+ UTF-8
+
+
+
+ /Users/edburns/Documents/JavaEE/workareas/mojarra-dependencies/trinidad-assembly-2.0.0-beta-1/src/trinidad-api-2.0.0-beta-1-sources
+
@@ -88,6 +108,14 @@
jsf-ri/test
+
+
+ /Users/edburns/Documents/chaff/netbeans-hack-links/jsf-api-test
+
+
+
+ /Users/edburns/Documents/JavaEE/workareas/mojarra-dependencies/trinidad-assembly-2.0.0-beta-1/src/trinidad-api-2.0.0-beta-1-sources
+
build.xml
@@ -109,7 +137,9 @@
jsf-ri/test
jsf-api/build/generate
jsf-ri/build/generate
- dependencies/jars/jsp-api-2.1.jar:dependencies/jars/jstl-1.2.jar:dependencies/jars/validation-api-1.0.0.GA.jar:dependencies/jars/servlet-api-3.0.20100224.jar:dependencies/jars/groovy-all-1.6.9.jar:dependencies/jars/junit-3.8.1.jar:lib/jsf-extensions-test-time.jar:lib/cactus-1.7.1-javaee5.jar:dependencies/jars/cdi-api-1.0-SP1.jar:dependencies/jars/javax.inject-1.0-PFD-1.jar:${container.home}/modules/el-impl.jar:${container.home}/modules/bean-validator.jar:${container.home}/modules/javax.servlet.jsp.jar:${container.home}/modules/javax.servlet.jar
+ /Users/edburns/Documents/chaff/netbeans-hack-links/jsf-api-test
+ /Users/edburns/Documents/JavaEE/workareas/mojarra-dependencies/trinidad-assembly-2.0.0-beta-1/src/trinidad-api-2.0.0-beta-1-sources
+ dependencies/jars/jsp-api-2.1.jar:dependencies/jars/jstl-1.2.jar:dependencies/jars/validation-api-1.0.0.GA.jar:dependencies/jars/servlet-api-3.0.20100224.jar:dependencies/jars/groovy-all-1.6.9.jar:dependencies/jars/junit-3.8.1.jar:lib/jsf-extensions-test-time.jar:lib/cactus-1.7.1-javaee5.jar:dependencies/jars/cdi-api-1.0-SP1.jar:dependencies/jars/javax.inject-1.0-PFD-1.jar:/Users/edburns/Documents/JavaEE/runtimes/glassfish-3.1-mojarra-shared/glassfish3/glassfish/modules/el-impl.jar:/Users/edburns/Documents/JavaEE/runtimes/glassfish-3.1-mojarra-shared/glassfish3/glassfish/modules/bean-validator.jar:/Users/edburns/Documents/JavaEE/runtimes/glassfish-3.1-mojarra-shared/glassfish3/glassfish/modules/javax.servlet.jsp.jar:/Users/edburns/Documents/JavaEE/runtimes/glassfish-3.1-mojarra-shared/glassfish3/glassfish/modules/javax.servlet.jar:jsf-api/build/classes
1.5
Index: jsf-api/src/test/java/javax/faces/component/NamingContainerTestCase.java
===================================================================
--- jsf-api/src/test/java/javax/faces/component/NamingContainerTestCase.java (revision 8870)
+++ jsf-api/src/test/java/javax/faces/component/NamingContainerTestCase.java (working copy)
@@ -117,16 +117,16 @@
request.setAttribute("reqScopeName", "reqScopeValue");
response = new MockHttpServletResponse();
+ externalContext =
+ new MockExternalContext(servletContext, request, response);
+ lifecycle = new MockLifecycle();
+ facesContext = new MockFacesContext(externalContext, lifecycle);
// Set up Faces API Objects
FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY,
"com.sun.faces.mock.MockApplicationFactory");
FactoryFinder.setFactory(FactoryFinder.RENDER_KIT_FACTORY,
"com.sun.faces.mock.MockRenderKitFactory");
- externalContext =
- new MockExternalContext(servletContext, request, response);
- lifecycle = new MockLifecycle();
- facesContext = new MockFacesContext(externalContext, lifecycle);
ApplicationFactory applicationFactory = (ApplicationFactory)
FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
application = (MockApplication) applicationFactory.getApplication();
Index: jsf-api/src/test/java/javax/faces/component/UIComponentTestCase.java
===================================================================
--- jsf-api/src/test/java/javax/faces/component/UIComponentTestCase.java (revision 8870)
+++ jsf-api/src/test/java/javax/faces/component/UIComponentTestCase.java (working copy)
@@ -164,18 +164,18 @@
request.setAttribute("reqScopeName", "reqScopeValue");
response = new MockHttpServletResponse();
+ externalContext =
+ new MockExternalContext(servletContext, request, response);
+ Map map = new HashMap();
+ externalContext.setRequestParameterMap(map);
+ lifecycle = new MockLifecycle();
+ facesContext = new MockFacesContext(externalContext, lifecycle);
// Set up Faces API Objects
FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY,
"com.sun.faces.mock.MockApplicationFactory");
FactoryFinder.setFactory(FactoryFinder.RENDER_KIT_FACTORY,
"com.sun.faces.mock.MockRenderKitFactory");
- externalContext =
- new MockExternalContext(servletContext, request, response);
- Map map = new HashMap();
- externalContext.setRequestParameterMap(map);
- lifecycle = new MockLifecycle();
- facesContext = new MockFacesContext(externalContext, lifecycle);
ApplicationFactory applicationFactory = (ApplicationFactory)
FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
application = (MockApplication) applicationFactory.getApplication();
Index: jsf-api/src/test/java/javax/faces/validator/ValidatorTestCase.java
===================================================================
--- jsf-api/src/test/java/javax/faces/validator/ValidatorTestCase.java (revision 8870)
+++ jsf-api/src/test/java/javax/faces/validator/ValidatorTestCase.java (working copy)
@@ -124,16 +124,16 @@
request.setAttribute("reqScopeName", "reqScopeValue");
response = new MockHttpServletResponse();
+ externalContext =
+ new MockExternalContext(servletContext, request, response);
+ lifecycle = new MockLifecycle();
+ facesContext = new MockFacesContext(externalContext, lifecycle);
// Set up Faces API Objects
FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY,
"com.sun.faces.mock.MockApplicationFactory");
FactoryFinder.setFactory(FactoryFinder.RENDER_KIT_FACTORY,
"com.sun.faces.mock.MockRenderKitFactory");
- externalContext =
- new MockExternalContext(servletContext, request, response);
- lifecycle = new MockLifecycle();
- facesContext = new MockFacesContext(externalContext, lifecycle);
ApplicationFactory applicationFactory = (ApplicationFactory)
FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
application = (MockApplication) applicationFactory.getApplication();
Index: jsf-api/src/test/java/javax/faces/webapp/TagTestCaseBase.java
===================================================================
--- jsf-api/src/test/java/javax/faces/webapp/TagTestCaseBase.java (revision 8870)
+++ jsf-api/src/test/java/javax/faces/webapp/TagTestCaseBase.java (working copy)
@@ -142,16 +142,16 @@
pageContext.initialize(servlet, request, response, null,
true, 1024, true);
+ externalContext =
+ new MockExternalContext(servletContext, request, response);
+ externalContext.setRequestParameterMap(new HashMap());
+ lifecycle = new MockLifecycle();
+ facesContext = new MockFacesContext(externalContext, lifecycle);
// Set up Faces API Objects
FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY,
"com.sun.faces.mock.MockApplicationFactory");
FactoryFinder.setFactory(FactoryFinder.RENDER_KIT_FACTORY,
"com.sun.faces.mock.MockRenderKitFactory");
- externalContext =
- new MockExternalContext(servletContext, request, response);
- externalContext.setRequestParameterMap(new HashMap());
- lifecycle = new MockLifecycle();
- facesContext = new MockFacesContext(externalContext, lifecycle);
ApplicationFactory applicationFactory = (ApplicationFactory)
FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
application = (MockApplication) applicationFactory.getApplication();
Index: jsf-api/src/main/java/javax/faces/FactoryFinder.java
===================================================================
--- jsf-api/src/main/java/javax/faces/FactoryFinder.java (revision 8870)
+++ jsf-api/src/main/java/javax/faces/FactoryFinder.java (working copy)
@@ -67,6 +67,8 @@
import java.lang.reflect.Constructor;
import java.net.URL;
import java.net.URLConnection;
+import java.util.Set;
+import javax.faces.context.FacesContext;
/**
@@ -680,8 +682,8 @@
*/
private static final class FactoryManagerCache {
- private ConcurrentMap> applicationMap =
- new ConcurrentHashMap>();
+ private ConcurrentMap> applicationMap =
+ new ConcurrentHashMap>();
// ------------------------------------------------------ Public Methods
@@ -689,8 +691,10 @@
private FactoryManager getApplicationFactoryManager(ClassLoader cl) {
+ FactoryManagerCacheKey key = new FactoryManagerCacheKey(cl, applicationMap);
+
while (true) {
- Future factories = applicationMap.get(cl);
+ Future factories = applicationMap.get(key);
if (factories == null) {
Callable callable =
new Callable() {
@@ -702,7 +706,7 @@
FutureTask ft =
new FutureTask(callable);
- factories = applicationMap.putIfAbsent(cl, ft);
+ factories = applicationMap.putIfAbsent(key, ft);
if (factories == null) {
factories = ft;
ft.run();
@@ -717,14 +721,14 @@
ce.toString(),
ce);
}
- applicationMap.remove(cl);
+ applicationMap.remove(key);
} catch (InterruptedException ie) {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.log(Level.FINEST,
ie.toString(),
ie);
}
- applicationMap.remove(cl);
+ applicationMap.remove(key);
} catch (ExecutionException ee) {
throw new FacesException(ee);
}
@@ -735,14 +739,89 @@
public void removeApplicationFactoryManager(ClassLoader cl) {
+ FactoryManagerCacheKey key = new FactoryManagerCacheKey(cl, applicationMap);
- applicationMap.remove(cl);
+ applicationMap.remove(key);
}
} // END FactoryCache
+ private static final class FactoryManagerCacheKey {
+ private ClassLoader cl;
+ private Object context;
+ private static final String KEY = FactoryFinder.class.getName() + "." +
+ FactoryManagerCacheKey.class.getSimpleName();
+
+ public FactoryManagerCacheKey(ClassLoader cl,
+ Map> factoryMap) {
+ this.cl = cl;
+ FacesContext facesContext = FacesContext.getCurrentInstance();
+ if (null != facesContext) {
+ Map appMap = facesContext.getExternalContext().getApplicationMap();
+ Object val = appMap.get(KEY);
+ if (null == val) {
+ context = new Long(System.currentTimeMillis());
+ appMap.put(KEY, context);
+ } else {
+ context = val;
+ }
+ } else {
+ // We don't have a FacesContext.
+ // Our only recourse is to inspect the keys of the
+ // factoryMap and see if any of them has a classloader
+ // equal to our argument cl.
+ Set keys = factoryMap.keySet();
+ FactoryManagerCacheKey match = null;
+ for (FactoryManagerCacheKey cur : keys) {
+ if (this.cl.equals(cur.cl)) {
+ match = cur;
+ if (null != match) {
+ LOGGER.log(Level.WARNING, "Multiple JSF Applications found on same ClassLoader. Unable to safely determine which FactoryManager instance to use. Defaulting to first match.");
+ }
+ }
+ }
+ if (null != match) {
+ this.context = match.context;
+ }
+ }
+ }
+
+ private FactoryManagerCacheKey() {}
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final FactoryManagerCacheKey other = (FactoryManagerCacheKey) obj;
+ if (this.cl != other.cl && (this.cl == null || !this.cl.equals(other.cl))) {
+ return false;
+ }
+ if (this.context != other.context && (this.context == null || !this.context.equals(other.context))) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 97 * hash + (this.cl != null ? this.cl.hashCode() : 0);
+ hash = 97 * hash + (this.context != null ? this.context.hashCode() : 0);
+ return hash;
+ }
+
+
+
+
+ }
+
+
/**
* Maintains the factories for a single web application.
*/
Index: jsf-ri/test/com/sun/faces/config/TestFactoryInjection.java
===================================================================
--- jsf-ri/test/com/sun/faces/config/TestFactoryInjection.java (revision 8870)
+++ jsf-ri/test/com/sun/faces/config/TestFactoryInjection.java (working copy)
@@ -235,7 +235,9 @@
// invoke the FactoryConfigProcessor
FactoryConfigProcessor fcp = new FactoryConfigProcessor(false);
+ InitFacesContext initContext = new InitFacesContext(sc);
fcp.process(sc, new DocumentInfo[]{new DocumentInfo(d, null)});
+ initContext.release();
// now get an FacesContext instance from the Factory and ensure
// no injection occured.
@@ -264,7 +266,9 @@
// process the document. This should cause the the InjectionFacesContextFactory
// to be put into play since there is more than one FacesContextFactory
// being configured
+ initContext = new InitFacesContext(sc);
fcp.process(sc, new DocumentInfo[]{new DocumentInfo(d, null)});
+ initContext.release();
// get the FacesContextFactory instance. The top-level factory should
// be the InjectionFacesContextFactory.
Index: jsf-ri/src/main/java/com/sun/faces/config/ConfigureListener.java
===================================================================
--- jsf-ri/src/main/java/com/sun/faces/config/ConfigureListener.java (revision 8870)
+++ jsf-ri/src/main/java/com/sun/faces/config/ConfigureListener.java (working copy)
@@ -348,6 +348,7 @@
ApplicationAssociate.setCurrentInstance(null);
// Release the initialization mark on this web application
ConfigManager.getInstance().destory(context);
+ FactoryFinder.releaseFactories();
if (initContext != null) {
initContext.release();
}
Index: jsf-ri/build.xml
===================================================================
--- jsf-ri/build.xml (revision 8870)
+++ jsf-ri/build.xml (working copy)
@@ -700,7 +700,7 @@
-
@@ -715,6 +715,14 @@
+
+
+
+
+
+
+
Index: jsf-ri/build-tests.xml
===================================================================
--- jsf-ri/build-tests.xml (revision 8870)
+++ jsf-ri/build-tests.xml (working copy)
@@ -552,8 +552,6 @@
-
-
+ name="com.sun.faces.config.TestFactoryInjection"/>
Index: jsf-ri/systest-per-webapp/build.xml
===================================================================
--- jsf-ri/systest-per-webapp/build.xml (revision 8870)
+++ jsf-ri/systest-per-webapp/build.xml (working copy)
@@ -165,6 +165,7 @@
+
Index: jsf-ri/systest-per-webapp/replace-lifecycle/src/java/com/sun/faces/systest/SimplePhaseListener.java
===================================================================
--- jsf-ri/systest-per-webapp/replace-lifecycle/src/java/com/sun/faces/systest/SimplePhaseListener.java (revision 8870)
+++ jsf-ri/systest-per-webapp/replace-lifecycle/src/java/com/sun/faces/systest/SimplePhaseListener.java (working copy)
@@ -43,6 +43,7 @@
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
+import java.util.Map;
public class SimplePhaseListener implements PhaseListener {
@@ -57,8 +58,12 @@
public void beforePhase(PhaseEvent event) {
- event.getFacesContext().getExternalContext().getRequestMap().put("beforePhase",
- "beforePhase");
+ Map requestMap =
+ event.getFacesContext().getExternalContext().getRequestMap();
+ String message = requestMap.containsKey("beforePhase") ?
+ requestMap.get("beforePhase").toString() : "";
+ requestMap.put("beforePhase",
+ message + " beforePhase");
event.getFacesContext().getExternalContext().getRequestMap().put("lifecycleImpl",
event.getSource());
}
Index: jsf-ri/systest-per-webapp/replace-lifecycle/src/java/com/sun/faces/systest/ReplaceLifecycleTestCase.java
===================================================================
--- jsf-ri/systest-per-webapp/replace-lifecycle/src/java/com/sun/faces/systest/ReplaceLifecycleTestCase.java (revision 8870)
+++ jsf-ri/systest-per-webapp/replace-lifecycle/src/java/com/sun/faces/systest/ReplaceLifecycleTestCase.java (working copy)
@@ -128,7 +128,10 @@
public void testReplaceLifecycle() throws Exception {
HtmlPage page = getPage("/faces/test.jsp");
- assertTrue(-1 != page.asText().indexOf("beforePhase"));
+ String pageText = page.asText();
+ assertTrue(-1 != pageText.indexOf("beforePhase"));
+ // Ensure the phaseListener is only called once.
+ assertTrue(!pageText.matches("(?s).*beforePhase.*beforePhase.*"));
}
Index: lib/jsf-extensions-test-time.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream