[richfaces-svn-commits] JBoss Rich Faces SVN: r18316 - in root/sandbox: cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk and 7 other directories.

richfaces-svn-commits at lists.jboss.org richfaces-svn-commits at lists.jboss.org
Sun Aug 1 10:55:35 EDT 2010


Author: nbelaevski
Date: 2010-08-01 10:55:34 -0400 (Sun, 01 Aug 2010)
New Revision: 18316

Added:
   root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ProcessMode.java
   root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/resource/StaticResourcesScannerImpl.java
   root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/util/
   root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/util/ClasspathUtil.java
   root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/util/ConcurrentHashSet.java
   root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/util/MorePredicates.java
Removed:
   root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ResourceProducer.java
Modified:
   root/sandbox/cdk/dynamic-resources-prerenderer/src/it/richfaces-application/pom.xml
   root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ProcessMojo.java
   root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ResourceInfo.java
   root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ResourceWriter.java
   root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/naming/FileNameMapperImpl.java
   root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/resource/ReflectionsExt.java
   root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/resource/ResourceWriterImpl.java
   root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/resource/ResourcesScannerImpl.java
   root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/task/ResourceTaskFactoryImpl.java
   root/sandbox/examples/pom.xml
   root/sandbox/examples/richfaces-showcase-gae/pom.xml
   root/sandbox/examples/richfaces-showcase-gae/src/main/java/org/richfaces/resource/DictionaryResourceHandlerImpl.java
Log:
dynamic-resources-prerenderer: latest changes check-in

Modified: root/sandbox/cdk/dynamic-resources-prerenderer/src/it/richfaces-application/pom.xml
===================================================================
--- root/sandbox/cdk/dynamic-resources-prerenderer/src/it/richfaces-application/pom.xml	2010-07-31 12:31:36 UTC (rev 18315)
+++ root/sandbox/cdk/dynamic-resources-prerenderer/src/it/richfaces-application/pom.xml	2010-08-01 14:55:34 UTC (rev 18316)
@@ -16,7 +16,6 @@
                 <executions>
                     <execution>
                         <id>process</id>
-                        <phase>generate-resources</phase>
                         <goals>
                             <goal>process</goal>
                         </goals>

Added: root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ProcessMode.java
===================================================================
--- root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ProcessMode.java	                        (rev 0)
+++ root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ProcessMode.java	2010-08-01 14:55:34 UTC (rev 18316)
@@ -0,0 +1,32 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * 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.
+ */
+package org.richfaces.cdk;
+
+/**
+ * @author Nick Belaevski
+ * 
+ */
+public enum ProcessMode {
+
+    external, embedded
+    
+}

Modified: root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ProcessMojo.java
===================================================================
--- root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ProcessMojo.java	2010-07-31 12:31:36 UTC (rev 18315)
+++ root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ProcessMojo.java	2010-08-01 14:55:34 UTC (rev 18316)
@@ -25,7 +25,6 @@
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLClassLoader;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
@@ -48,17 +47,19 @@
 import org.richfaces.cdk.naming.FileNameMapperImpl;
 import org.richfaces.cdk.resource.ResourceWriterImpl;
 import org.richfaces.cdk.resource.ResourcesScannerImpl;
+import org.richfaces.cdk.resource.StaticResourcesScannerImpl;
 import org.richfaces.cdk.task.ResourceTaskFactoryImpl;
+import org.richfaces.cdk.util.ClasspathUtil;
+import org.richfaces.cdk.util.MorePredicates;
 
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
 import com.google.common.base.Predicates;
-import com.google.common.collect.Collections2;
 
 /**
  * @goal process
  * @requiresDependencyResolution compile
- * @phase generate-resources
+ * @phase process-classes
  */
 public class ProcessMojo extends AbstractMojo {
 
@@ -67,7 +68,7 @@
             return Predicates.containsPattern(from);
         };
     };
-    
+
     private static final Function<Resource, String> CONTENT_TYPE_FUNCTION = new Function<Resource, String>() {
         public String apply(Resource from) {
             return from.getContentType();
@@ -109,33 +110,38 @@
     // TODO review usage of properties?
     private Properties fileNameMappings;
 
+    /**
+     * @parameter
+     */
+    private ProcessMode processMode = ProcessMode.embedded;
+
+    private String webRoot;
+    
     // TODO executor parameters
     private static ExecutorService createExecutorService() {
         return Executors.newSingleThreadExecutor();
     }
 
     private Predicate<Resource> createResourcesFilter() {
-        List<Predicate<CharSequence>> contentTypePredicates = new ArrayList<Predicate<CharSequence>>();
-        
-        if (includedContentTypes != null && !includedContentTypes.isEmpty()) {
-            Collection<Predicate<CharSequence>> predicates = Collections2.transform(includedContentTypes, REGEX_CONTAINS_BUILDER_FUNCTION);
+        Predicate<CharSequence> contentTypePredicate = MorePredicates.compose(includedContentTypes,
+            excludedContentTypes, REGEX_CONTAINS_BUILDER_FUNCTION);
+        return Predicates.compose(contentTypePredicate, CONTENT_TYPE_FUNCTION);
+    }
 
-            //hack for JDK - the code doesn't compile without this variable
-            Predicate<CharSequence> predicate = Predicates.or(predicates);
-            contentTypePredicates.add(predicate);
+    private ResourcesScanner createResourcesScanner() {
+        Collection<URL> urls = ClasspathUtil.getFacesClasspathUrls();
+        switch (processMode) {
+            case external:
+                //TODO webroot
+                return new StaticResourcesScannerImpl(urls, null);
+            case embedded:
+                return new ResourcesScannerImpl(urls);
+                
+            default:
+                throw new IllegalArgumentException();
         }
-        if (excludedContentTypes != null && !excludedContentTypes.isEmpty()) {
-            Collection<Predicate<CharSequence>> predicates = Collections2.transform(excludedContentTypes, REGEX_CONTAINS_BUILDER_FUNCTION);
-            
-            //hack for JDK - the code doesn't compile without this variable
-            Predicate<CharSequence> predicate = Predicates.or(predicates);
-            predicate = Predicates.not(predicate);
-            contentTypePredicates.add(predicate);
-        }
-
-        return Predicates.compose(Predicates.and(contentTypePredicates), CONTENT_TYPE_FUNCTION);
     }
-
+    
     protected ClassLoader createProjectClassLoader(MavenProject project, boolean useCCL) {
         ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
 
@@ -152,7 +158,7 @@
 
                 urls[i++] = new File(element).toURI().toURL();
             }
-
+            
             if (useCCL) {
                 classLoader = new URLClassLoader(urls, classLoader);
             } else {
@@ -179,7 +185,7 @@
 
             File outputDirFile = new File(outputDir);
             if (!outputDirFile.exists()) {
-                outputDirFile = new File(project.getBuild().getOutputDirectory(), outputDir);
+                outputDirFile = new File(project.getBuild().getDirectory(), outputDir);
             }
 
             ResourceWriterImpl resourceWriter = new ResourceWriterImpl(outputDirFile);
@@ -190,7 +196,7 @@
             faces = new FacesImpl(null, new FileNameMapperImpl(fileNameMappings), taskFactory);
             faces.start();
 
-            ResourcesScanner resourcesScanner = new ResourcesScannerImpl();
+            ResourcesScanner resourcesScanner = createResourcesScanner();
             resourcesScanner.scan();
 
             executorService = createExecutorService();
@@ -217,6 +223,8 @@
                     break;
                 }
             }
+            
+            resourceWriter.writeProcessedResourceMappings();
         } catch (Exception e) {
             throw new MojoExecutionException(e.getMessage(), e);
         } finally {

Modified: root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ResourceInfo.java
===================================================================
--- root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ResourceInfo.java	2010-07-31 12:31:36 UTC (rev 18315)
+++ root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ResourceInfo.java	2010-08-01 14:55:34 UTC (rev 18316)
@@ -31,6 +31,8 @@
 
     public static final String CLASSPATH_RESOURCES_LOCATION = "META-INF/resources/";
     
+    public static final String WEB_RESOURCES_LOCATION = "resources/";
+
     private final String resourceName;
     
     private final String libraryName;

Deleted: root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ResourceProducer.java
===================================================================
--- root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ResourceProducer.java	2010-07-31 12:31:36 UTC (rev 18315)
+++ root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ResourceProducer.java	2010-08-01 14:55:34 UTC (rev 18316)
@@ -1,34 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2010, Red Hat, Inc. and individual contributors
- * 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.
- */
-package org.richfaces.cdk;
-
-import javax.faces.application.Resource;
-
-/**
- * @author Nick Belaevski
- * 
- */
-public interface ResourceProducer {
-
-    public Resource build();
-    
-}

Modified: root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ResourceWriter.java
===================================================================
--- root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ResourceWriter.java	2010-07-31 12:31:36 UTC (rev 18315)
+++ root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ResourceWriter.java	2010-08-01 14:55:34 UTC (rev 18316)
@@ -32,5 +32,7 @@
 public interface ResourceWriter {
 
     public void writeResource(String skinName, Resource resource) throws IOException;
+
+    public void writeProcessedResourceMappings() throws IOException;
     
 }

Modified: root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/naming/FileNameMapperImpl.java
===================================================================
--- root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/naming/FileNameMapperImpl.java	2010-07-31 12:31:36 UTC (rev 18315)
+++ root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/naming/FileNameMapperImpl.java	2010-08-01 14:55:34 UTC (rev 18316)
@@ -30,8 +30,9 @@
 import javax.faces.application.Resource;
 
 import org.richfaces.cdk.FileNameMapper;
+import org.richfaces.resource.VersionedResource;
 
-import com.google.common.base.Strings;
+import com.google.common.base.Joiner;
 import com.google.common.collect.Lists;
 
 /**
@@ -111,23 +112,17 @@
     
     @Override
     public String createName(Resource resource) {
-        StringBuilder result = new StringBuilder();
-
-        String libraryName = resource.getLibraryName();
-        if (!Strings.isNullOrEmpty(libraryName)) {
-            result.append(libraryName);
-            result.append('/');
+        String resourceVersion = null;
+        if (resource instanceof VersionedResource) {
+            resourceVersion = ((VersionedResource) resource).getVersion();
         }
-
-        result.append(resource.getResourceName());
         
+        String resourcePath = Joiner.on('/').skipNulls().join(resource.getLibraryName(), resourceVersion, resource.getResourceName());
         String fileExt = stripContentClassifier(resource.getContentType());
-        if (fileExt != null && fileExt.length() != 0) {
-            result.append('.');
-            result.append(fileExt);
-        }
+
+        resourcePath = Joiner.on('.').skipNulls().join(resourcePath, fileExt);
         
-        return remapName(result.toString());
+        return remapName(resourcePath);
     }
 
 }

Modified: root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/resource/ReflectionsExt.java
===================================================================
--- root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/resource/ReflectionsExt.java	2010-07-31 12:31:36 UTC (rev 18315)
+++ root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/resource/ReflectionsExt.java	2010-08-01 14:55:34 UTC (rev 18316)
@@ -21,23 +21,15 @@
  */
 package org.richfaces.cdk.resource;
 
-import static com.google.common.collect.Collections2.filter;
-
-import java.text.MessageFormat;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Map;
-import java.util.Set;
-import java.util.regex.Pattern;
 
 import org.reflections.Configuration;
 import org.reflections.Reflections;
 import org.reflections.scanners.Scanner;
 import org.reflections.util.Utils;
-import org.richfaces.cdk.ResourceInfo;
 
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
 import com.google.common.collect.Multimap;
 
 /**
@@ -46,18 +38,6 @@
  */
 class ReflectionsExt extends Reflections {
 
-    private static final Predicate<String> ECSS_RESOURCE_PREDICATE = new Predicate<String>() {
-
-        private final Pattern pathPattern = Pattern.compile(MessageFormat.format("^{0}.+\\.ecss$", 
-            ResourceInfo.CLASSPATH_RESOURCES_LOCATION));
-
-        @Override
-        public boolean apply(String input) {
-            return pathPattern.matcher(input).matches();
-        }
-
-    };
-
     public ReflectionsExt() {
         super();
     }
@@ -78,9 +58,5 @@
         }
         return Utils.forNames(scannerMMap.get(MarkerResourcesScanner.STORE_KEY));
     }
-    
-    public Collection<String> getURLResources() {
-        Set<String> allResources = getResources(Predicates.<String> alwaysTrue());
-        return filter(allResources, ECSS_RESOURCE_PREDICATE);
-    }
+
 }

Modified: root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/resource/ResourceWriterImpl.java
===================================================================
--- root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/resource/ResourceWriterImpl.java	2010-07-31 12:31:36 UTC (rev 18315)
+++ root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/resource/ResourceWriterImpl.java	2010-08-01 14:55:34 UTC (rev 18316)
@@ -25,6 +25,9 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
 
 import javax.faces.application.Resource;
 
@@ -32,6 +35,8 @@
 import org.richfaces.cdk.FileNameMapper;
 import org.richfaces.cdk.ResourceWriter;
 
+import com.google.common.base.Joiner;
+import com.google.common.base.Strings;
 import com.google.common.io.ByteStreams;
 
 /**
@@ -42,27 +47,47 @@
 
     private File baseDir;
     
+    private Map<String, String> processedResources = new ConcurrentHashMap<String, String>();
+    
     public ResourceWriterImpl(File baseDir) {
         this.baseDir = baseDir;
         baseDir.mkdirs();
     }
 
+    private String getResourceQualifier(Resource resource) {
+        return Joiner.on(':').skipNulls().join(resource.getLibraryName(), resource.getResourceName());
+    }
+    
     private FileNameMapper getFileNameMapper() {
         return ServiceTracker.getService(FileNameMapper.class);
     }
     
+    private File getRoot(String rootName) {
+        return new File(baseDir, rootName);
+    }
+    
+    private String addSkinPrefix(String s) {
+        return "%skin%/" + s;
+    }
+    
     public void writeResource(String skinName, Resource resource) throws IOException {
         FileOutputStream fos = null;
         InputStream is = null;
         try {
             is = resource.getInputStream();
-            File skinDir = new File(baseDir, skinName);
-            File outFile = new File(skinDir, getFileNameMapper().createName(resource));
+            String mappedName = getFileNameMapper().createName(resource);
+            File outFile = new File(getRoot(skinName), mappedName);
             outFile.getParentFile().mkdirs();
             outFile.createNewFile();
             
             fos = new FileOutputStream(outFile);
             ByteStreams.copy(is, fos);
+            
+            if (!Strings.isNullOrEmpty(skinName)) {
+                mappedName = addSkinPrefix(mappedName);
+            }
+            
+            processedResources.put(getResourceQualifier(resource), mappedName);
         } finally {
             if (fos != null) {
                 try {
@@ -83,4 +108,27 @@
         }
     }
 
+    @Override
+    public void writeProcessedResourceMappings() throws IOException {
+        FileOutputStream fos = null;
+        try {
+            File mappingsFile = new File(baseDir, "org.richfaces/resource-mappings.properties");
+            mappingsFile.getParentFile().mkdirs();
+            mappingsFile.createNewFile();
+            
+            fos = new FileOutputStream(mappingsFile);
+            Properties properties = new Properties();
+            properties.putAll(processedResources);
+            properties.store(fos, null);
+        } finally {
+            try {
+                if (fos != null) {
+                    fos.close();
+                }
+            } catch (IOException e) {
+                // TODO: handle exception
+            }
+        }
+    }
+
 }

Modified: root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/resource/ResourcesScannerImpl.java
===================================================================
--- root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/resource/ResourcesScannerImpl.java	2010-07-31 12:31:36 UTC (rev 18315)
+++ root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/resource/ResourcesScannerImpl.java	2010-08-01 14:55:34 UTC (rev 18316)
@@ -30,20 +30,13 @@
 
 import org.reflections.scanners.SubTypesScanner;
 import org.reflections.scanners.TypeAnnotationsScanner;
-import org.reflections.util.ClasspathHelper;
 import org.reflections.util.ConfigurationBuilder;
-import org.reflections.vfs.Vfs;
-import org.reflections.vfs.Vfs.Dir;
-import org.reflections.vfs.Vfs.File;
-import org.reflections.vfs.ZipDir;
 import org.richfaces.cdk.ResourceInfo;
 import org.richfaces.cdk.ResourcesScanner;
 import org.richfaces.resource.DynamicResource;
 
 import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Collections2;
-import com.google.common.collect.Iterators;
+import com.google.common.collect.Iterables;
 import com.google.common.collect.Sets;
 /**
  * @author Nick Belaevski
@@ -59,76 +52,27 @@
         }
     };
     
-    private static final Function<String, ResourceInfo> RELATIVE_PATH_FUNCTION = new Function<String, ResourceInfo>() {
+    private Collection<ResourceInfo> resources = Sets.newHashSet();
 
-        private String getResourceRelativePath(String path) {
-            return path.substring(ResourceInfo.CLASSPATH_RESOURCES_LOCATION.length());
-        }
-        
-        private String getLibraryName(String relativePath) {
-            int idx = relativePath.lastIndexOf('/');
-            if (idx < 0) {
-                return null;
-            } else {
-                return relativePath.substring(0, idx);
-            }
-        }
-        
-        private String getResourceName(String relativePath) {
-            int idx = relativePath.lastIndexOf('/');
-            if (idx < 0) {
-                return relativePath;
-            } else {
-                return relativePath.substring(idx + 1);
-            }
-        }
-
-        @Override
-        public ResourceInfo apply(String from) {
-            String relPath = getResourceRelativePath(from);
-            String libraryName = getLibraryName(relPath);
-            String resourceName = getResourceName(relPath);
-            return new ResourceInfo(resourceName, libraryName);
-        }
-    };
+    private Collection<URL> urls;
     
-    private static final Predicate<File> IS_FACES_CONFIG = new Predicate<File>() {
-
-        public boolean apply(File input) {
-            return input.getRelativePath().endsWith("META-INF/faces-config.xml");
-        }
-
-    };
-
-    private static final Predicate<URL> FACES_URL = new Predicate<URL>() {
-        
-        public boolean apply(URL input) {
-            Dir dir = Vfs.fromURL(input);
-            if (dir instanceof ZipDir) {
-                return containsFacesConfig(dir);
-            } else {
-                return true;
-            }
-        }
-    };
-    
-    private Collection<ResourceInfo> resources = Sets.newHashSet();
-    
-    private static boolean containsFacesConfig(Dir dir) {
-        return Iterators.any(dir.getFiles().iterator(), IS_FACES_CONFIG);
+    public ResourcesScannerImpl(Collection<URL> urls) {
+        super();
+        this.urls = urls;
     }
 
+    protected Collection<URL> getUrls() {
+        return urls;
+    }
+    
     public void scan() {
         resources.clear();
-        
-        Collection<URL> urls = Collections2.filter(ClasspathHelper.getUrlsForCurrentClasspath(), FACES_URL);
 
         ConfigurationBuilder configurationBuilder = new ConfigurationBuilder().setUrls(urls);
         configurationBuilder.setScanners(new SubTypesScanner(), new TypeAnnotationsScanner(),
-            new MarkerResourcesScanner(), new org.reflections.scanners.ResourcesScanner());
+            new MarkerResourcesScanner());
 
         ReflectionsExt refl = new ReflectionsExt(configurationBuilder);
-
         Set<Class<?>> classResources = refl.getTypesAnnotatedWith(DynamicResource.class);
 
         // TODO - reflections library doesn't handle @Inherited correctly
@@ -138,9 +82,12 @@
         }
 
         resources.addAll(transform(refl.getMarkedClasses(), CLASS_RESOURCE_FUNCTION));
-        resources.addAll(transform(refl.getURLResources(), RELATIVE_PATH_FUNCTION));
     }
 
+    protected void addResources(Iterable<ResourceInfo> infos) {
+        Iterables.addAll(resources, infos);
+    }
+    
     @Override
     public Collection<ResourceInfo> getResources() {
         return resources;

Added: root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/resource/StaticResourcesScannerImpl.java
===================================================================
--- root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/resource/StaticResourcesScannerImpl.java	                        (rev 0)
+++ root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/resource/StaticResourcesScannerImpl.java	2010-08-01 14:55:34 UTC (rev 18316)
@@ -0,0 +1,126 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * 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.
+ */
+package org.richfaces.cdk.resource;
+
+import static com.google.common.collect.Iterables.transform;
+import static java.util.Collections.singleton;
+
+import java.net.URL;
+import java.util.Collection;
+
+import org.reflections.vfs.Vfs;
+import org.reflections.vfs.Vfs.File;
+import org.richfaces.cdk.ResourceInfo;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+
+/**
+ * @author Nick Belaevski
+ * 
+ */
+public class StaticResourcesScannerImpl extends ResourcesScannerImpl {
+
+    private static class RelativePathStartsWithPredicate implements Predicate<File> {
+
+        private String prefix;
+        
+        public RelativePathStartsWithPredicate(String prefix) {
+            super();
+            this.prefix = prefix;
+        }
+
+        @Override
+        public boolean apply(File input) {
+            return input.getRelativePath().startsWith(prefix);
+        }
+    }
+
+    private static class RelativePathResourceFunction implements Function<File, ResourceInfo> {
+
+        private String prefix;
+        
+        public RelativePathResourceFunction(String prefix) {
+            super();
+            this.prefix = prefix;
+        }
+
+        private String getResourceRelativePath(File file) {
+            return file.getRelativePath().substring(prefix.length());
+        }
+        
+        private String getLibraryName(String relativePath) {
+            int idx = relativePath.lastIndexOf('/');
+            if (idx < 0) {
+                return null;
+            } else {
+                return relativePath.substring(0, idx);
+            }
+        }
+        
+        private String getResourceName(String relativePath) {
+            int idx = relativePath.lastIndexOf('/');
+            if (idx < 0) {
+                return relativePath;
+            } else {
+                return relativePath.substring(idx + 1);
+            }
+        }
+
+        @Override
+        public ResourceInfo apply(File from) {
+            String relPath = getResourceRelativePath(from);
+            String libraryName = getLibraryName(relPath);
+            String resourceName = getResourceName(relPath);
+            return new ResourceInfo(resourceName, libraryName);
+        }
+    }
+    
+    private static final Predicate<File> CLASSPATH_RESOURCE_PREDICATE = new RelativePathStartsWithPredicate(ResourceInfo.CLASSPATH_RESOURCES_LOCATION);
+    private static final Predicate<File> WEB_RESOURCE_PREDICATE = new RelativePathStartsWithPredicate(ResourceInfo.WEB_RESOURCES_LOCATION);
+
+    private static final Function<File, ResourceInfo> CLASSPATH_RESOURCE_FUNCTION = new RelativePathResourceFunction(ResourceInfo.CLASSPATH_RESOURCES_LOCATION);
+    private static final Function<File, ResourceInfo> WEB_RESOURCE_FUNCTION = new RelativePathResourceFunction(ResourceInfo.WEB_RESOURCES_LOCATION);
+    
+    private URL webRootUrl;
+    
+    public StaticResourcesScannerImpl(Collection<URL> cpUrls, URL webRootUrl) {
+        super(cpUrls);
+        
+        this.webRootUrl = webRootUrl;
+    }
+
+    private void addResources(Collection<URL> urls, Predicate<Vfs.File> filter, Function<Vfs.File, ResourceInfo> transformer) {
+        Iterable<File> classpathResources = Vfs.findFiles(urls, filter);
+        addResources(transform(classpathResources, transformer));
+    }
+    
+    @Override
+    public void scan() {
+        super.scan();
+        
+        addResources(getUrls(), CLASSPATH_RESOURCE_PREDICATE, CLASSPATH_RESOURCE_FUNCTION);
+        if (webRootUrl != null) {
+            addResources(singleton(webRootUrl), WEB_RESOURCE_PREDICATE, WEB_RESOURCE_FUNCTION);
+        }
+    }
+}
\ No newline at end of file

Modified: root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/task/ResourceTaskFactoryImpl.java
===================================================================
--- root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/task/ResourceTaskFactoryImpl.java	2010-07-31 12:31:36 UTC (rev 18315)
+++ root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/task/ResourceTaskFactoryImpl.java	2010-08-01 14:55:34 UTC (rev 18316)
@@ -24,7 +24,6 @@
 import java.text.MessageFormat;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CompletionService;
-import java.util.concurrent.ConcurrentMap;
 
 import javax.faces.application.Resource;
 import javax.faces.component.StateHolder;
@@ -36,11 +35,11 @@
 import org.richfaces.cdk.ResourceTaskFactory;
 import org.richfaces.cdk.ResourceWriter;
 import org.richfaces.cdk.faces.CurrentResourceContext;
+import org.richfaces.cdk.util.ConcurrentHashSet;
 import org.richfaces.resource.StateHolderResource;
 
 import com.google.common.base.Predicate;
 import com.google.common.base.Predicates;
-import com.google.common.collect.Maps;
 import com.google.common.io.ByteArrayDataOutput;
 import com.google.common.io.ByteStreams;
 
@@ -52,12 +51,13 @@
 
     private class ResourcesRendererCallable implements Callable<Object> {
 
-        private String skinName;
-        
         private ResourceInfo resourceInfo;
         
-        ResourcesRendererCallable(String skinName, ResourceInfo resourceInfo) {
-            this.skinName = skinName;
+        private boolean skinDependent;
+        
+        private boolean skipped = false;
+        
+        ResourcesRendererCallable(ResourceInfo resourceInfo) {
             this.resourceInfo = resourceInfo;
         }
 
@@ -66,22 +66,15 @@
                 resourceInfo.getLibraryName());
         }
         
-        private void renderResource() {
+        private void renderResource(String skin) {
             try {
-                faces.setSkin(skinName);
                 FacesContext facesContext = faces.startRequest();
                 
-                Resource resource = createResource(facesContext, resourceInfo);
-                
-                if (resource == null) {
-                    //TODO log null resource
-                    return;
+                if (skin != null) {
+                    faces.setSkin(skin);
                 }
-
-                if (!filter.apply(resource)) {
-                    return;
-                }
                 
+                Resource resource = createResource(facesContext, resourceInfo);
                 CurrentResourceContext.getInstance(facesContext).setResource(resource);
                 
                 if (resource instanceof StateHolderResource) {
@@ -99,17 +92,61 @@
                 }
                 
                 //TODO check content type
-                resourceWriter.writeResource(skinName, resource);
+                resourceWriter.writeResource(skin, resource);
             } catch (Exception e) {
-                log.error(MessageFormat.format("Exception rendering resorce {0} using skin {1}: {2}", resourceInfo, skinName, e.getMessage()), e);
+                if (skin != null) {
+                    log.error(MessageFormat.format("Exception rendering resorce {0} using skin {1}: {2}", resourceInfo, skin, e.getMessage()), e);
+                } else {
+                    log.error(MessageFormat.format("Exception rendering resorce {0}: {1}", resourceInfo, e.getMessage()), e);
+                }
             } finally {
                 faces.setSkin(null);
                 faces.stopRequest();
             }
         }
+
+        private void checkResource() {
+            try {
+                FacesContext facesContext = faces.startRequest();
+                
+                Resource resource = createResource(facesContext, resourceInfo);
+                if (resource == null) {
+                    //TODO log null resource
+                    skipped = true;
+                    return;
+                }
+
+                if (!filter.apply(resource)) {
+                    skipped = true;
+                    return;
+                }
+                
+                String contentType = resource.getContentType();
+                if (contentType == null) {
+                    //TODO log null content type
+                    skipped = true;
+                    return;
+                }
+                
+                if (contentType.contains("css") || contentType.contains("image")) {
+                    skinDependent = true;
+                }
+            } finally {
+                faces.stopRequest();
+            }
+        }
         
         public Object call() throws Exception {
-            renderResource();
+            checkResource();
+            if (!skipped) {
+                if (skinDependent) {
+                    for (String skin : skins) {
+                        renderResource(skin);
+                    }
+                } else {
+                    renderResource(null);
+                }
+            }
             return null;
         }
         
@@ -121,7 +158,7 @@
     
     private ResourceWriter resourceWriter;
     
-    private ConcurrentMap<ResourceInfo, Boolean> submittedResources = Maps.newConcurrentMap();
+    private ConcurrentHashSet<ResourceInfo> submittedResources = new ConcurrentHashSet<ResourceInfo>();
     
     private CompletionService<Object> completionService;
     
@@ -155,11 +192,8 @@
     
     @Override
     public void submit(ResourceInfo info) {
-        if (submittedResources.putIfAbsent(info, Boolean.TRUE) == null) {
-            for (String skinName: skins) {
-                completionService.submit(new ResourcesRendererCallable(skinName, info));
-            }
+        if (submittedResources.addIfAbsent(info)) {
+            completionService.submit(new ResourcesRendererCallable(info));
         }
     }
-    
 }

Added: root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/util/ClasspathUtil.java
===================================================================
--- root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/util/ClasspathUtil.java	                        (rev 0)
+++ root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/util/ClasspathUtil.java	2010-08-01 14:55:34 UTC (rev 18316)
@@ -0,0 +1,73 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * 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.
+ */
+package org.richfaces.cdk.util;
+
+import java.net.URL;
+import java.util.Collection;
+
+import org.reflections.util.ClasspathHelper;
+import org.reflections.vfs.Vfs;
+import org.reflections.vfs.Vfs.Dir;
+import org.reflections.vfs.Vfs.File;
+import org.reflections.vfs.ZipDir;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Iterators;
+
+/**
+ * @author Nick Belaevski
+ * 
+ */
+public final class ClasspathUtil {
+
+    private static final Predicate<File> IS_FACES_CONFIG = new Predicate<File>() {
+
+        public boolean apply(File input) {
+            return input.getRelativePath().endsWith("META-INF/faces-config.xml");
+        }
+
+    };
+
+    private static final Predicate<URL> FACES_URL = new Predicate<URL>() {
+
+        public boolean apply(URL input) {
+            Dir dir = Vfs.fromURL(input);
+            if (dir instanceof ZipDir) {
+                return containsFacesConfig(dir);
+            } else {
+                return true;
+            }
+        }
+    };
+
+    private ClasspathUtil() {}
+
+    private static boolean containsFacesConfig(Dir dir) {
+        return Iterators.any(dir.getFiles().iterator(), IS_FACES_CONFIG);
+    }
+
+    public static Collection<URL> getFacesClasspathUrls() {
+        return Collections2.filter(ClasspathHelper.getUrlsForCurrentClasspath(), FACES_URL);
+    }
+
+}

Added: root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/util/ConcurrentHashSet.java
===================================================================
--- root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/util/ConcurrentHashSet.java	                        (rev 0)
+++ root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/util/ConcurrentHashSet.java	2010-08-01 14:55:34 UTC (rev 18316)
@@ -0,0 +1,75 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * 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.
+ */
+package org.richfaces.cdk.util;
+
+import java.util.AbstractSet;
+import java.util.Iterator;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * @author Nick Belaevski
+ * 
+ */
+public class ConcurrentHashSet<E> extends AbstractSet<E> {
+
+    private ConcurrentMap<E, Boolean> backingMap = new ConcurrentHashMap<E, Boolean>();
+
+    @Override
+    public Iterator<E> iterator() {
+        return backingMap.keySet().iterator();
+    }
+
+    public boolean add(E e) {
+        return backingMap.put(e, Boolean.TRUE) == null;
+    }
+    
+    public boolean addIfAbsent(E e) {
+        return backingMap.putIfAbsent(e, Boolean.TRUE) == null;
+    }
+    
+    @Override
+    public boolean contains(Object o) {
+        return backingMap.containsKey(o);
+    }
+    
+    @Override
+    public boolean remove(Object o) {
+        return Boolean.TRUE.equals(backingMap.remove(o));
+    }
+    
+    @Override
+    public void clear() {
+        backingMap.clear();
+    }
+    
+    @Override
+    public int size() {
+        return backingMap.size();
+    }
+    
+    @Override
+    public boolean isEmpty() {
+        return backingMap.isEmpty();
+    }
+    
+}
\ No newline at end of file

Added: root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/util/MorePredicates.java
===================================================================
--- root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/util/MorePredicates.java	                        (rev 0)
+++ root/sandbox/cdk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/util/MorePredicates.java	2010-08-01 14:55:34 UTC (rev 18316)
@@ -0,0 +1,72 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc. and individual contributors
+ * 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.
+ */
+package org.richfaces.cdk.util;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+
+/**
+ * @author Nick Belaevski
+ * 
+ */
+public final class MorePredicates {
+
+    private MorePredicates() {}
+
+    public static <S, D> Predicate<D> any(Iterable<S> options, Function<S, Predicate<D>> function) {
+        if (options == null || Iterables.isEmpty(options)) {
+            return Predicates.alwaysTrue();
+        }
+        
+        return Predicates.or(Iterables.transform(options, function));
+    }
+
+    public static <S, D> Predicate<D> none(Iterable<S> options, Function<S, Predicate<D>> function) {
+        if (options == null || Iterables.isEmpty(options)) {
+            return Predicates.alwaysTrue();
+        }
+        
+        Predicate<D> compositePredicate = Predicates.or(Iterables.transform(options, function));
+        return Predicates.not(compositePredicate);
+    }
+    
+    public static <S, D> Predicate<D> compose(Iterable<S> includes, Iterable<S> excludes, Function<S, Predicate<D>> function) {
+        final Predicate<D> includesPredicate = any(includes, function);
+        final Predicate<D> excludesPredicate = none(excludes, function);
+        return new Predicate<D>() {
+            public boolean apply(D input) {
+                return includesPredicate.apply(input) && excludesPredicate.apply(input);
+            }
+        };
+    }
+
+    public static Predicate<String> startsWith(final String prefix) {
+        return new Predicate<String>() {
+            @Override
+            public boolean apply(String input) {
+                return input.startsWith(prefix);
+            }
+        };
+    } 
+}
\ No newline at end of file

Modified: root/sandbox/examples/pom.xml
===================================================================
--- root/sandbox/examples/pom.xml	2010-07-31 12:31:36 UTC (rev 18315)
+++ root/sandbox/examples/pom.xml	2010-08-01 14:55:34 UTC (rev 18316)
@@ -37,6 +37,7 @@
 
     <modules>
         <module>components</module>
+        <module>richfaces-showcase-gae</module>
     </modules>
 
     <build>

Modified: root/sandbox/examples/richfaces-showcase-gae/pom.xml
===================================================================
--- root/sandbox/examples/richfaces-showcase-gae/pom.xml	2010-07-31 12:31:36 UTC (rev 18315)
+++ root/sandbox/examples/richfaces-showcase-gae/pom.xml	2010-08-01 14:55:34 UTC (rev 18316)
@@ -244,8 +244,6 @@
                                 <skin>wine</skin>
                             </skins>
                             <includedContentTypes>
-                                <include>text/javascript</include>
-                                <include>text/css</include>
                                 <include>image/.+</include>
                             </includedContentTypes>
                             <fileNameMappings>
@@ -257,10 +255,6 @@
                                     <name>^org\.richfaces\.demo\.images\.</name>
                                     <value>org.richfaces.demo/images/</value>
                                 </property>
-                                <property>
-                                    <name>^css/</name>
-                                    <value>org.richfaces/css/</value>
-                                </property>
                             </fileNameMappings>
                         </configuration>
                     </execution>

Modified: root/sandbox/examples/richfaces-showcase-gae/src/main/java/org/richfaces/resource/DictionaryResourceHandlerImpl.java
===================================================================
--- root/sandbox/examples/richfaces-showcase-gae/src/main/java/org/richfaces/resource/DictionaryResourceHandlerImpl.java	2010-07-31 12:31:36 UTC (rev 18315)
+++ root/sandbox/examples/richfaces-showcase-gae/src/main/java/org/richfaces/resource/DictionaryResourceHandlerImpl.java	2010-08-01 14:55:34 UTC (rev 18316)
@@ -147,7 +147,7 @@
         if (Strings.isNullOrEmpty(libraryName)) {
             return resourceName;
         } else {
-            return libraryName + "/" + resourceName;
+            return libraryName + ":" + resourceName;
         }
     }
 



More information about the richfaces-svn-commits mailing list