Skip to content
This repository has been archived by the owner on Nov 17, 2017. It is now read-only.

Commit

Permalink
Merge branch 'feature/mobile' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
bleathem committed Sep 30, 2011
2 parents 7f8bbd4 + 6cf189f commit b0e07ad
Show file tree
Hide file tree
Showing 18 changed files with 1,099 additions and 66 deletions.
126 changes: 104 additions & 22 deletions maven-resources-plugin/src/main/java/org/richfaces/cdk/ProcessMojo.java
Expand Up @@ -32,37 +32,48 @@
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Set;
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 javax.faces.application.ResourceHandler;
import javax.faces.application.ResourceDependency;

import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.richfaces.application.Module;
import org.richfaces.application.ServiceException;
import org.richfaces.application.ServiceLoader;
import org.richfaces.application.ServiceTracker;
import org.richfaces.application.ServicesFactoryImpl;
import org.richfaces.cdk.concurrent.CountingExecutorCompletionService;
import org.richfaces.cdk.faces.FacesImpl;
import org.richfaces.cdk.faces.ServiceFactoryModule;
import org.richfaces.cdk.naming.FileNameMapperImpl;
import org.richfaces.cdk.resource.handler.impl.DynamicResourceHandler;
import org.richfaces.cdk.resource.handler.impl.StaticResourceHandler;
import org.richfaces.cdk.resource.scan.ResourcesScanner;
import org.richfaces.cdk.resource.scan.impl.DynamicResourcesScanner;
import org.richfaces.cdk.resource.scan.impl.ResourceOrderingScanner;
import org.richfaces.cdk.resource.scan.impl.StaticResourcesScanner;
import org.richfaces.cdk.resource.util.ResourceConstants;
import org.richfaces.cdk.resource.util.ResourceUtil;
import org.richfaces.cdk.resource.writer.ResourceProcessor;
import org.richfaces.cdk.resource.writer.impl.CSSResourceProcessor;
import org.richfaces.cdk.resource.writer.impl.JavaScriptResourceProcessor;
import org.richfaces.cdk.resource.writer.impl.CSSCompressingProcessor;
import org.richfaces.cdk.resource.writer.impl.JavaScriptCompressingProcessor;
import org.richfaces.cdk.resource.writer.impl.JavaScriptPackagingProcessor;
import org.richfaces.cdk.resource.writer.impl.ResourceWriterImpl;
import org.richfaces.cdk.task.ResourceTaskFactoryImpl;
import org.richfaces.cdk.util.MoreConstraints;
Expand All @@ -80,6 +91,7 @@
import com.google.common.base.Strings;
import com.google.common.collect.Constraints;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import com.google.common.collect.Sets;

/**
Expand All @@ -94,22 +106,16 @@ public Predicate<CharSequence> apply(String from) {
Predicate<CharSequence> containsPredicate = Predicates.containsPattern(from);
return Predicates.and(Predicates.notNull(), containsPredicate);
}

;
};
private static final Function<Resource, String> CONTENT_TYPE_FUNCTION = new Function<Resource, String>() {
public String apply(Resource from) {
return from.getContentType();
}

;
};
private static final Function<Resource, String> RESOURCE_QUALIFIER_FUNCTION = new Function<Resource, String>() {
public String apply(Resource from) {
return ResourceUtil.getResourceQualifier(from);
}

;
};
private final Function<String, URL> filePathToURL = new Function<String, URL>() {
public URL apply(String from) {
Expand All @@ -124,8 +130,6 @@ public URL apply(String from) {

return null;
}

;
};
/**
* @parameter
Expand Down Expand Up @@ -159,6 +163,14 @@ public URL apply(String from) {
* @parameter
*/
private List<String> excludedFiles;
/**
* @parameter
*/
private boolean compress = true;
/**
* @parameter
*/
private boolean pack = false;
/**
* @parameter
*/
Expand All @@ -179,23 +191,31 @@ public URL apply(String from) {
// TODO handle resource locales
private Locale resourceLocales;
private Collection<ResourceKey> foundResources = Sets.newHashSet();
private Ordering<ResourceKey> resourceOrdering;
private Set<ResourceKey> resourcesWithKnownOrder;

// TODO executor parameters
private static ExecutorService createExecutorService() {
return Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
private ExecutorService createExecutorService() {
int poolSize = pack ? 1 : Runtime.getRuntime().availableProcessors();
return Executors.newFixedThreadPool(poolSize);
}

private Collection<ResourceProcessor> getDefaultResourceProcessors() {

Charset charset = Charset.defaultCharset();
if (!Strings.isNullOrEmpty(encoding)) {
charset = Charset.forName(encoding);
} else {
getLog().warn(
"Encoding is not set explicitly, CDK resources plugin will use default platform encoding for processing char-based resources");
}

return Arrays.<ResourceProcessor>asList(new JavaScriptResourceProcessor(charset, getLog()), new CSSResourceProcessor(
charset));
if (compress) {
return Arrays.<ResourceProcessor>asList(new JavaScriptCompressingProcessor(charset, getLog()), new CSSCompressingProcessor(
charset));
} else {
return Arrays.<ResourceProcessor>asList(new JavaScriptPackagingProcessor(charset));
}

}

private Predicate<Resource> createResourcesFilter() {
Expand Down Expand Up @@ -235,6 +255,13 @@ private void scanStaticResources(Collection<VirtualFile> resourceRoots) throws E
foundResources.addAll(scanner.getResources());
}

private void scanResourceOrdering(Collection<VFSRoot> cpFiles) throws Exception {
ResourceOrderingScanner scanner = new ResourceOrderingScanner(cpFiles, getLog());
scanner.scan();
resourceOrdering = scanner.getCompleteOrdering();
resourcesWithKnownOrder = Sets.newLinkedHashSet(scanner.getResources());
}

private Collection<VFSRoot> fromUrls(Iterable<URL> urls) throws URISyntaxException, IOException {
Collection<VFSRoot> result = Lists.newArrayList();

Expand Down Expand Up @@ -281,6 +308,58 @@ protected ClassLoader createProjectClassLoader(URL[] cp) {
return classLoader;
}

/**
* Initializes {@link ServiceTracker} to be able use it inside RichFaces framework code
* in order to handle dynamic resources.
*
* Fake {@link ServiceFactoryModule} is used for this purpose.
*
* @throws IllegalStateException when initialization fails
*/
private void initializeServiceTracker() {
ServicesFactoryImpl servicesFactory = new ServicesFactoryImpl();
ServiceTracker.setFactory(servicesFactory);

ArrayList<Module> modules = new ArrayList<Module>();
modules.add(new ServiceFactoryModule());
try {
modules.addAll(ServiceLoader.loadServices(Module.class));
servicesFactory.init(modules);
} catch (ServiceException e) {
throw new IllegalStateException(e);
}
}

/**
* Will determine ordering of resources from {@link ResourceDependency} annotations on renderers.
*
* Sorts foundResources using the determined ordering.
*/
private void reorderFoundResources(Collection<VFSRoot> cpResources, DynamicResourceHandler dynamicResourceHandler, ResourceFactory resourceFactory) throws Exception {
Faces faces = new FacesImpl(null, new FileNameMapperImpl(fileNameMappings), dynamicResourceHandler);
faces.start();
initializeServiceTracker();

// if there are some resource libraries (.reslib), we need to expand them
foundResources = new ResourceLibraryExpander().expandResourceLibraries(foundResources);

faces.startRequest();
scanResourceOrdering(cpResources);
faces.stopRequest();

faces.stop();

foundResources = resourceOrdering.sortedCopy(foundResources);

// do not package two versions of JFS JavaScript (remove it from resources for packaging)
foundResources.remove(ResourceConstants.JSF_UNCOMPRESSED);
// we need to load java.faces:jsf-uncompressed.js, but we will package
resourcesWithKnownOrder.add(ResourceConstants.JSF_UNCOMPRESSED);

getLog().debug("foundResources: " + foundResources);
getLog().debug("resourcesWithKnownOrder: " + resourcesWithKnownOrder);
}

@Override
public void execute() throws MojoExecutionException, MojoFailureException {
ClassLoader contextCL = Thread.currentThread().getContextClassLoader();
Expand All @@ -305,22 +384,25 @@ public void execute() throws MojoExecutionException, MojoFailureException {

scanDynamicResources(cpResources, resourceFactory);

DynamicResourceHandler dynamicResourceHandler = new DynamicResourceHandler(staticResourceHandler, resourceFactory);

if (pack) {
reorderFoundResources(cpResources, dynamicResourceHandler, resourceFactory);
}

File resourceOutputDir = new File(outputDir);
if (!resourceOutputDir.exists()) {
resourceOutputDir = new File(project.getBuild().getDirectory(), outputDir);
}

File resourceMappingDir = new File(project.getBuild().getOutputDirectory());

ResourceHandler resourceHandler = new DynamicResourceHandler(staticResourceHandler, resourceFactory);

// TODO set webroot
faces = new FacesImpl(null, new FileNameMapperImpl(fileNameMappings), resourceHandler);
faces = new FacesImpl(null, new FileNameMapperImpl(fileNameMappings), dynamicResourceHandler);
faces.start();

ResourceWriterImpl resourceWriter = new ResourceWriterImpl(resourceOutputDir, resourceMappingDir,
getDefaultResourceProcessors(), getLog());
ResourceTaskFactoryImpl taskFactory = new ResourceTaskFactoryImpl(faces);
getDefaultResourceProcessors(), getLog(), resourcesWithKnownOrder);
ResourceTaskFactoryImpl taskFactory = new ResourceTaskFactoryImpl(faces, pack);
taskFactory.setResourceWriter(resourceWriter);

executorService = createExecutorService();
Expand Down
@@ -0,0 +1,74 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2011, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file 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 java.util.Collection;

import org.richfaces.application.ServiceTracker;
import org.richfaces.renderkit.html.ResourceLibraryRenderer;
import org.richfaces.resource.ResourceKey;
import org.richfaces.resource.ResourceLibrary;
import org.richfaces.resource.ResourceLibraryFactory;

import com.google.common.collect.Sets;

/**
* Expands resource libraries (.reslib).
*
* @author <a href="mailto:lfryc@redhat.com">Lukas Fryc</a>
*/
public class ResourceLibraryExpander {

/**
* Expands resource libraries (.reslib) in collection of resource keys.
*
* @param resources resource keys to be expanded
* @return collection with all resource libraries expanded to particular resource keys (keeps ordering)
*/
public Collection<ResourceKey> expandResourceLibraries(Collection<ResourceKey> resources) {
ResourceLibraryFactory factory = ServiceTracker.getService(ResourceLibraryFactory.class);
Collection<ResourceKey> expandedResources = Sets.newLinkedHashSet();

for (ResourceKey resourceKey : resources) {
if (resourceKey.getResourceName().endsWith(ResourceLibraryRenderer.RESOURCE_LIBRARY_EXTENSION)) {

String libraryName = resourceKey.getLibraryName();
String resourceName = resourceKey.getResourceName().substring(0,
resourceKey.getResourceName().length() - ResourceLibraryRenderer.RESOURCE_LIBRARY_EXTENSION.length());
ResourceLibrary resourceLibrary = factory.getResourceLibrary(resourceName, libraryName);

if (resourceLibrary == null) {
throw new IllegalArgumentException("Resource library is null: " + libraryName + ":" + resourceName);
}

for (ResourceKey expandedKey : resourceLibrary.getResources()) {
expandedResources.add(expandedKey);
}

} else {
expandedResources.add(resourceKey);
}
}

return expandedResources;
}
}
Expand Up @@ -31,6 +31,8 @@
*/
public interface ResourceWriter {
void writeResource(String skinName, Resource resource) throws IOException;

void writePackedResource(String skinName, Resource resource) throws IOException;

void writeProcessedResourceMappings() throws IOException;
}
Expand Up @@ -35,6 +35,7 @@
import java.util.Map;
import java.util.Set;

import javax.activation.MimetypesFileTypeMap;
import javax.faces.context.ExternalContext;

import com.google.common.collect.Sets;
Expand Down Expand Up @@ -448,4 +449,17 @@ public void redirect(String url) throws IOException {
public String getResponseCharacterEncoding() {
return "UTF-8";
}

/**
* Returns mime-type for known resorce file types
*
* @param file the full name of file
* @return mime-type for known resorce file types
*
* TODO load supported mime-types from mime.types file in this project
*/
@Override
public String getMimeType(String file) {
return MimetypesFileTypeMap.getDefaultFileTypeMap().getContentType(file);
}
}

0 comments on commit b0e07ad

Please sign in to comment.