Author: nbelaevski
Date: 2010-07-28 19:01:27 -0400 (Wed, 28 Jul 2010)
New Revision: 18268
Added:
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/config/
Modified:
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/pom.xml
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/it/richfaces-application/pom.xml
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ProcessMojo.java
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ResourceTaskFactory.java
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/naming/FileNameMapperImpl.java
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/resource/URLResource.java
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/task/ResourceTaskFactoryImpl.java
Log:
Dynamic resources prerenderer: added filtering by content types
Modified: root/cdk-sandbox/trunk/dynamic-resources-prerenderer/pom.xml
===================================================================
--- root/cdk-sandbox/trunk/dynamic-resources-prerenderer/pom.xml 2010-07-28 20:02:51 UTC
(rev 18267)
+++ root/cdk-sandbox/trunk/dynamic-resources-prerenderer/pom.xml 2010-07-28 23:01:27 UTC
(rev 18268)
@@ -73,6 +73,7 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
+ <version>r06</version>
</dependency>
<dependency>
Modified:
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/it/richfaces-application/pom.xml
===================================================================
---
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/it/richfaces-application/pom.xml 2010-07-28
20:02:51 UTC (rev 18267)
+++
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/it/richfaces-application/pom.xml 2010-07-28
23:01:27 UTC (rev 18268)
@@ -25,10 +25,27 @@
<skins>
<skin>blueSky</skin>
<skin>classic</skin>
+ <skin>deepMarine</skin>
+ <skin>emeraldTown</skin>
+ <skin>japanCherry</skin>
<skin>ruby</skin>
- <skin>emeraldTown</skin>
<skin>wine</skin>
</skins>
+ <includedContentTypes>
+ <include>text/javascript</include>
+ <include>text/css</include>
+ <include>image/.+</include>
+ </includedContentTypes>
+ <fileNameMappings>
+ <property>
+
<name>^org\.richfaces\.renderkit\.html\.(images\.)?</name>
+ <value>org.richfaces/images/</value>
+ </property>
+ <property>
+ <name>^css/</name>
+ <value>org.richfaces/css/</value>
+ </property>
+ </fileNameMappings>
</configuration>
</execution>
</executions>
Modified:
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ProcessMojo.java
===================================================================
---
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ProcessMojo.java 2010-07-28
20:02:51 UTC (rev 18267)
+++
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ProcessMojo.java 2010-07-28
23:01:27 UTC (rev 18268)
@@ -25,14 +25,19 @@
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;
+import java.util.Properties;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
+import javax.faces.application.Resource;
+
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
@@ -45,6 +50,11 @@
import org.richfaces.cdk.resource.ResourcesScannerImpl;
import org.richfaces.cdk.task.ResourceTaskFactoryImpl;
+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
@@ -52,28 +62,80 @@
*/
public class ProcessMojo extends AbstractMojo {
+ private static final Function<String, Predicate<CharSequence>>
REGEX_CONTAINS_BUILDER_FUNCTION = new Function<String,
Predicate<CharSequence>>() {
+ public Predicate<CharSequence> apply(String from) {
+ 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();
+ };
+ };
+
/**
* @parameter
* @required
*/
private String outputDir;
-
+
/**
* @parameter
* @required
*/
+ // TODO handle base skins
private String[] skins;
-
+
/**
* @parameter expression="${project}"
* @readonly
*/
private MavenProject project;
-
+
+ /**
+ * @parameter
+ */
+ private List<String> includedContentTypes;
+
+ /**
+ * @parameter
+ */
+ private List<String> excludedContentTypes;
+
+ /**
+ * @parameter
+ */
+ // TODO review usage of properties?
+ private Properties fileNameMappings;
+
+ // 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);
+
+ //hack for JDK - the code doesn't compile without this variable
+ Predicate<CharSequence> predicate = Predicates.or(predicates);
+ contentTypePredicates.add(predicate);
+ }
+ 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();
@@ -85,7 +147,7 @@
urls[i++] = new File(outputDirectory).toURI().toURL();
- for (Iterator<?> iter = compileClasspathElements.iterator();
iter.hasNext(); ) {
+ for (Iterator<?> iter = compileClasspathElements.iterator();
iter.hasNext();) {
String element = (String) iter.next();
urls[i++] = new File(element).toURI().toURL();
@@ -110,24 +172,24 @@
ClassLoader cCL = Thread.currentThread().getContextClassLoader();
Faces faces = null;
ExecutorService executorService = null;
-
+
try {
ClassLoader projectCL = createProjectClassLoader(project, true);
Thread.currentThread().setContextClassLoader(projectCL);
-
+
File outputDirFile = new File(outputDir);
if (!outputDirFile.exists()) {
outputDirFile = new File(project.getBuild().getOutputDirectory(),
outputDir);
}
-
+
ResourceWriterImpl resourceWriter = new ResourceWriterImpl(outputDirFile);
ResourceTaskFactoryImpl taskFactory = new ResourceTaskFactoryImpl();
taskFactory.setResourceWriter(resourceWriter);
// TODO set webroot
- faces = new FacesImpl(null, new FileNameMapperImpl(), taskFactory);
+ faces = new FacesImpl(null, new FileNameMapperImpl(fileNameMappings),
taskFactory);
faces.start();
-
+
ResourcesScanner resourcesScanner = new ResourcesScannerImpl();
resourcesScanner.scan();
@@ -136,6 +198,7 @@
taskFactory.setCompletionService(completionService);
taskFactory.setSkins(skins);
taskFactory.setLog(getLog());
+ taskFactory.setFilter(createResourcesFilter());
for (ResourceInfo resourceInfo : resourcesScanner.getResources()) {
taskFactory.submit(resourceInfo);
}
@@ -157,7 +220,7 @@
} catch (Exception e) {
throw new MojoExecutionException(e.getMessage(), e);
} finally {
- //TODO review finally block
+ // TODO review finally block
if (executorService != null) {
executorService.shutdown();
}
@@ -167,5 +230,4 @@
Thread.currentThread().setContextClassLoader(cCL);
}
}
-
}
Modified:
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ResourceTaskFactory.java
===================================================================
---
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ResourceTaskFactory.java 2010-07-28
20:02:51 UTC (rev 18267)
+++
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/ResourceTaskFactory.java 2010-07-28
23:01:27 UTC (rev 18268)
@@ -23,6 +23,10 @@
import java.util.concurrent.CompletionService;
+import javax.faces.application.Resource;
+
+import com.google.common.base.Predicate;
+
/**
* @author Nick Belaevski
*
@@ -37,6 +41,8 @@
public void setResourceWriter(ResourceWriter resourceWriter);
+ public void setFilter(Predicate<Resource> filter);
+
public void submit(ResourceInfo info);
}
Modified:
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/naming/FileNameMapperImpl.java
===================================================================
---
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/naming/FileNameMapperImpl.java 2010-07-28
20:02:51 UTC (rev 18267)
+++
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/naming/FileNameMapperImpl.java 2010-07-28
23:01:27 UTC (rev 18268)
@@ -21,8 +21,9 @@
*/
package org.richfaces.cdk.naming;
-import java.util.Map;
+import java.util.List;
import java.util.Map.Entry;
+import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -31,7 +32,7 @@
import org.richfaces.cdk.FileNameMapper;
import com.google.common.base.Strings;
-import com.google.common.collect.Maps;
+import com.google.common.collect.Lists;
/**
* @author Nick Belaevski
@@ -39,12 +40,46 @@
*/
public class FileNameMapperImpl implements FileNameMapper {
- private Map<String, String> mappedPackages = Maps.newLinkedHashMap();
+ private static final class Mapping {
+
+ private Pattern pattern;
+
+ private String replacement;
+
+ public Mapping(Pattern pattern, String replacement) {
+ super();
+ this.pattern = pattern;
+ this.replacement = replacement;
+ }
+
+ public Pattern getPattern() {
+ return pattern;
+ }
+
+ public String getReplacement() {
+ return replacement;
+ }
+ }
- {
-
mappedPackages.put("^org\\.richfaces\\.renderkit\\.html\\.(images\\.)?",
"org.richfaces/images/");
- mappedPackages.put("^css/", "org/richfaces/css/");
+ private List<Mapping> fileNameMappings;
+
+ public FileNameMapperImpl(Properties fileNameMappings) {
+ super();
+ this.fileNameMappings = compileMappings(fileNameMappings);
}
+
+ private static List<Mapping> compileMappings(Properties properties) {
+ List<Mapping> result = Lists.newArrayList();
+
+ for (Entry<Object, Object> entry: properties.entrySet()) {
+ Pattern pattern = Pattern.compile((String) entry.getKey());
+ String replacement = (String) entry.getValue();
+
+ result.add(new Mapping(pattern, replacement));
+ }
+
+ return result;
+ }
private String stripContentClassifier(String mimeType) {
if (mimeType == null) {
@@ -64,10 +99,10 @@
return name;
}
- for (Entry<String, String> mapping : mappedPackages.entrySet()) {
- Matcher matcher = Pattern.compile(mapping.getKey()).matcher(name);
+ for (Mapping mapping : fileNameMappings) {
+ Matcher matcher = mapping.getPattern().matcher(name);
if (matcher.find()) {
- return matcher.replaceAll(mapping.getValue());
+ return matcher.replaceAll(mapping.getReplacement());
}
}
Modified:
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/resource/URLResource.java
===================================================================
---
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/resource/URLResource.java 2010-07-28
20:02:51 UTC (rev 18267)
+++
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/resource/URLResource.java 2010-07-28
23:01:27 UTC (rev 18268)
@@ -26,6 +26,8 @@
import java.net.URL;
import java.util.Map;
+import javax.activation.FileTypeMap;
+import javax.activation.MimetypesFileTypeMap;
import javax.faces.application.Resource;
import javax.faces.context.FacesContext;
@@ -68,4 +70,14 @@
public boolean userAgentNeedsUpdate(FacesContext context) {
throw new UnsupportedOperationException();
}
+
+ /* (non-Javadoc)
+ * @see javax.faces.application.Resource#getContentType()
+ */
+ @Override
+ public String getContentType() {
+ FileTypeMap typeMap = MimetypesFileTypeMap.getDefaultFileTypeMap();
+
+ return typeMap.getContentType(resourceUrl.getFile());
+ }
}
Modified:
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/task/ResourceTaskFactoryImpl.java
===================================================================
---
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/task/ResourceTaskFactoryImpl.java 2010-07-28
20:02:51 UTC (rev 18267)
+++
root/cdk-sandbox/trunk/dynamic-resources-prerenderer/src/main/java/org/richfaces/cdk/task/ResourceTaskFactoryImpl.java 2010-07-28
23:01:27 UTC (rev 18268)
@@ -38,6 +38,8 @@
import org.richfaces.cdk.faces.CurrentResourceContext;
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;
@@ -76,6 +78,10 @@
return;
}
+ if (!filter.apply(resource)) {
+ return;
+ }
+
CurrentResourceContext.getInstance(facesContext).setResource(resource);
if (resource instanceof StateHolderResource) {
@@ -121,6 +127,8 @@
private String[] skins = new String[0];
+ private Predicate<Resource> filter = Predicates.alwaysTrue();
+
public void setLog(Log log) {
this.log = log;
}
@@ -141,6 +149,10 @@
this.completionService = completionService;
}
+ public void setFilter(Predicate<Resource> filter) {
+ this.filter = filter;
+ }
+
@Override
public void submit(ResourceInfo info) {
if (submittedResources.putIfAbsent(info, Boolean.TRUE) == null) {