dev@javaserverfaces.java.net

Seeking Review: 1856 composite jar without directories not found

From: Edward Burns <edward.burns_at_oracle.com>
Date: Wed, 23 Mar 2011 16:01:33 -0400

Another revision: Don't even try to detect the existence of a library from the xmlns case unless the context param is set http://java.net/jira/browse/JAVASERVERFACES-1856


SECTION: Modified Files
----------------------------
M jsf-ri/test/com/sun/faces/application/resource/TestResourceHandlerImpl.java

- TCK testcase idea from Doug.

M jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/CompositeComponentTagLibrary.java

- Move the composite library detection up here.

M jsf-ri/src/main/java/com/sun/faces/application/resource/ClasspathResourceHelper.java

- Do the ZipDirectoryScan as lazily as possible.

SECTION: Diffs
----------------------------
Index: jsf-ri/test/com/sun/faces/application/resource/TestResourceHandlerImpl.java
===================================================================
--- jsf-ri/test/com/sun/faces/application/resource/TestResourceHandlerImpl.java (revision 8946)
+++ jsf-ri/test/com/sun/faces/application/resource/TestResourceHandlerImpl.java (working copy)
@@ -902,7 +902,15 @@
 
     }
 
+ public void testLibraryExistsNegative() throws Exception {
+ ResourceHandler handler = getFacesContext().getApplication().getResourceHandler();
+ assertNotNull(handler);
 
+ assertFalse(handler.libraryExists("oeunhtnhtnhhnhh"));
+
+ }
+
+
     //==========================================================================
     // Validate the fix for issue 1162.
     //
Index: jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/CompositeComponentTagLibrary.java
===================================================================
--- jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/CompositeComponentTagLibrary.java (revision 8946)
+++ jsf-ri/src/main/java/com/sun/faces/facelets/tag/jsf/CompositeComponentTagLibrary.java (working copy)
@@ -58,6 +58,8 @@
 
 package com.sun.faces.facelets.tag.jsf;
 
+import com.sun.faces.config.WebConfiguration;
+import static com.sun.faces.config.WebConfiguration.BooleanWebContextInitParameter.EnableEarlyMissingResourceLibraryDetection;
 import com.sun.faces.facelets.tag.TagLibraryImpl;
 import com.sun.faces.util.FacesLogger;
 
@@ -84,6 +86,7 @@
             throw new NullPointerException();
         }
         this.ns = ns;
+ this.init();
     }
     
     public CompositeComponentTagLibrary(String ns, String compositeLibraryName) {
@@ -96,11 +99,19 @@
             throw new NullPointerException();
         }
         this.compositeLibraryName = compositeLibraryName;
+ this.init();
         
     }
+
+ private void init() {
+ WebConfiguration webconfig = WebConfiguration.getInstance();
+ enableEarlyMissingResourceLibraryDetection =
+ webconfig.isOptionEnabled(EnableEarlyMissingResourceLibraryDetection);
+ }
     
     private String ns = null;
     private String compositeLibraryName;
+ private boolean enableEarlyMissingResourceLibraryDetection;
 
     public boolean containsTagHandler(String ns, String localName) {
         boolean result = false;
@@ -162,8 +173,12 @@
         
         String resourceId = null;
         if (null != (resourceId = getCompositeComponentLibraryName(toTest))) {
- result = FacesContext.getCurrentInstance().getApplication().
- getResourceHandler().libraryExists(resourceId);
+ if (enableEarlyMissingResourceLibraryDetection) {
+ result = FacesContext.getCurrentInstance().getApplication().
+ getResourceHandler().libraryExists(resourceId);
+ } else {
+ result = true;
+ }
         }
         
         return result;
Index: jsf-ri/src/main/java/com/sun/faces/application/resource/ClasspathResourceHelper.java
===================================================================
--- jsf-ri/src/main/java/com/sun/faces/application/resource/ClasspathResourceHelper.java (revision 8946)
+++ jsf-ri/src/main/java/com/sun/faces/application/resource/ClasspathResourceHelper.java (working copy)
@@ -40,6 +40,9 @@
 
 package com.sun.faces.application.resource;
 
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.Map;
+import java.util.Iterator;
 import java.util.Set;
 import java.io.IOException;
 import java.io.InputStream;
@@ -51,7 +54,6 @@
 import com.sun.faces.util.Util;
 
 import static com.sun.faces.config.WebConfiguration.BooleanWebContextInitParameter.CacheResourceModificationTimestamp;
-import static com.sun.faces.config.WebConfiguration.BooleanWebContextInitParameter.EnableEarlyMissingResourceLibraryDetection;
 
 
 /**
@@ -67,7 +69,7 @@
 
     private static final String BASE_RESOURCE_PATH = "META-INF/resources";
     private boolean cacheTimestamp;
- private ZipDirectoryEntryScanner libraryScanner;
+ private Map<Boolean, ZipDirectoryEntryScanner> libraryScannerHolder;
 
 
     // ------------------------------------------------------------ Constructors
@@ -77,9 +79,7 @@
 
         WebConfiguration webconfig = WebConfiguration.getInstance();
         cacheTimestamp = webconfig.isOptionEnabled(CacheResourceModificationTimestamp);
- if (webconfig.isOptionEnabled(EnableEarlyMissingResourceLibraryDetection)) {
- libraryScanner = new ZipDirectoryEntryScanner();
- }
+ libraryScannerHolder = new ConcurrentHashMap<Boolean, ZipDirectoryEntryScanner>(1);
     }
 
 
@@ -157,14 +157,31 @@
             if (basePathURL == null) {
                 // This does not work on GlassFish 3.1 due to GLASSFISH-16229.
                 Set<String> resourcePaths = ctx.getExternalContext().getResourcePaths("/" + libraryName + "/");
- if (null == resourcePaths || resourcePaths.isEmpty()) {
- // If we get to this point and we are being asked to find a localized "javax.faces"
- // library, we must truly try to look for the library, and tell
- // the caller the true answer.
- if ((null != localePrefix && libraryName.equals("javax.faces")) ||
- null != libraryScanner && !libraryScanner.libraryExists(libraryName)) {
+ if (null != resourcePaths && !resourcePaths.isEmpty()) {
+ boolean foundEntryStartingWithMetaInfResources = false;
+ Iterator<String> iter = resourcePaths.iterator();
+ // Ensure that at least one entry starts with /META-INF/resources.
+ while (!foundEntryStartingWithMetaInfResources && iter.hasNext()) {
+ foundEntryStartingWithMetaInfResources = iter.next().startsWith("/META-INF/resources");
+ }
+ if (!foundEntryStartingWithMetaInfResources) {
                         return null;
                     }
+ } else {
+ //
+ if (null != localePrefix && libraryName.equals("javax.faces")) {
+ return null;
+ }
+
+ // housekeeping for concurrency
+ ZipDirectoryEntryScanner scanner = libraryScannerHolder.get(Boolean.TRUE);
+ if (null == scanner) {
+ scanner = new ZipDirectoryEntryScanner();
+ libraryScannerHolder.put(Boolean.TRUE, scanner);
+ }
+ if (!scanner.libraryExists(libraryName)) {
+ return null;
+ }
                 }
             }
         }