Java tutorial
/** * License Agreement. * * Rich Faces - Natural Ajax for Java Server Faces (JSF) * * Copyright (C) 2007 Exadel, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1 as published by the Free Software Foundation. * * This library 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package org.richfaces.cdk.rd.mojo; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.apache.commons.digester.Digester; import org.apache.commons.vfs.FileObject; import org.apache.commons.vfs.FileSystemException; import org.apache.commons.vfs.FileSystemManager; import org.apache.commons.vfs.VFS; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.factory.ArtifactFactory; import org.apache.maven.artifact.metadata.ArtifactMetadataSource; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.resolver.ArtifactNotFoundException; import org.apache.maven.artifact.resolver.ArtifactResolutionException; import org.apache.maven.artifact.resolver.ArtifactResolutionResult; import org.apache.maven.artifact.resolver.ArtifactResolver; import org.apache.maven.model.Dependency; import org.apache.maven.model.Resource; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.logging.Log; import org.apache.maven.project.MavenProject; import org.apache.maven.project.artifact.MavenMetadataSource; import org.codehaus.classworlds.ClassRealm; import org.codehaus.classworlds.ClassWorld; import org.codehaus.plexus.util.DirectoryScanner; import org.codehaus.plexus.velocity.VelocityComponent; import org.richfaces.cdk.rd.Components; import org.richfaces.cdk.rd.generator.ResourceAssembler; import org.richfaces.cdk.rd.generator.ResourcesGenerator; import org.richfaces.cdk.rd.generator.ScriptAssembler; import org.richfaces.cdk.rd.generator.StyleAssembler; import org.richfaces.cdk.rd.handler.ComponentsHandler; import org.richfaces.cdk.rd.utils.PluginUtils; /** * @author Anton Belevich * @goal assembly-resources * @phase generate-resources * */ public class ResourceDependencyMojo extends AbstractMojo { /** * Top maven project. * * @parameter expression="${project}" * @readonly */ MavenProject project; /** * Used to look up Artifacts in the remote repository. * * @component */ private ArtifactFactory factory; /** * Used to look up Artifacts in the remote repository. * * @component */ private ArtifactResolver resolver; /** * * @component */ private ArtifactMetadataSource metadataSource; /** * @component */ protected VelocityComponent velocity; /** * The local repository. * * @parameter expression="${localRepository}" */ private ArtifactRepository localRepository; /** * webSourceDirectory * * @parameter expression="${basedir}/src/main/webapp" */ private File webSourceDirectory; /** * scriptFilePath * @parameter expression="custom-dependencies" */ private String scriptFilePath; /** * outputResourceDirectory * @parameter expression="${project.build.directory}/generated-resources * */ private File outputResourceDirectory; /** * styleFilePath * @parameter expression="custom-dependencies" */ private String styleFilePath; /** * beforeScriptIncludes * @parameter */ private List<String> beforeScriptIncludes; /** * afterScriptIncludes * @parameter */ private List<String> afterScriptIncludes; /** * beforeStyleIncludes * @parameter */ private List<String> beforeStyleIncludes; /** * afterStyleIncludes * @parameter */ private List<String> afterStyleIncludes; /** * scriptIncludes * @parameter */ private String[] scriptIncludes; /** * scriptExcludes * @parameter */ private String[] scriptExcludes; /** * styleIncludes * @parameter */ private String[] styleIncludes; /** * styleExcludes * @parameter */ private String[] styleExcludes; /** * namespaceIncludes * @parameter */ private String[] namespaceIncludes; /** * namespaceExcludes * @parameter */ private String[] namespaceExcludes; /** * componentIncludes * @parameter */ private String[] componentIncludes; /** * componentExcludes * @parameter */ private String[] componentExcludes; /** * xmlConfigPatterns * @parameter */ private String[] xmlConfigPatterns; /** * xhtmlIncludes * @parameter */ private String[] xhtmlIncludes; /** * xhtmlExcludes * @parameter */ private String[] xhtmlExcludes; public void execute() throws MojoExecutionException, MojoFailureException { try { Set<Artifact> artifacts = resolveDependenciesArtifacts(); Digester defaultDigester = createDigester(); Map<String, Components> components = new HashMap<String, Components>(); if (xmlConfigPatterns == null) { xmlConfigPatterns = PluginUtils.DEFAULT_CONFIG_PATTERNS; } for (Artifact artifact : artifacts) { FileObject jar = resolveArtifact(artifact); getLog().info("Process jar: " + jar.getName().getFriendlyURI()); FileObject[] configs = PluginUtils.resolveConfigsFromJar(jar, xmlConfigPatterns); if (configs.length == 0) { getLog().info("no dependecy files found"); } else { getLog().info("next dependency files found"); for (FileObject config : configs) { getLog().info(config.getName().getBaseName()); } } components.putAll(PluginUtils.processConfigs(configs, defaultDigester)); } if (!webSourceDirectory.exists()) { webSourceDirectory.mkdirs(); } ComponentsHandler handler = findComponents(webSourceDirectory, components, xhtmlIncludes, xhtmlExcludes); ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); ClassLoader contextClassLoader = createClassLoader(); Thread.currentThread().setContextClassLoader(contextClassLoader); if (contextClassLoader != null) { Set<String> scripts = handler.getScripts(); scriptFilePath = scriptFilePath.endsWith(".js") ? scriptFilePath : scriptFilePath + ".js"; File scriptFile = new File(outputResourceDirectory, scriptFilePath); if (!scriptFile.exists()) { File parent = scriptFile.getParentFile(); if (parent != null && !parent.exists()) { parent.mkdirs(); } } ScriptAssembler scriptAssembler = new ScriptAssembler(getLog()); if (!scripts.isEmpty()) { getLog().info("Start merge scripts to the: " + scriptFile.getPath()); mergeResources(scriptFile, scriptAssembler, beforeScriptIncludes, afterScriptIncludes, scripts); } Set<String> styles = handler.getStyles(); styleFilePath = styleFilePath.endsWith(".xcss") ? styleFilePath : styleFilePath + ".xcss"; File styleFile = new File(outputResourceDirectory, styleFilePath); File parent = styleFile.getParentFile(); if (parent != null && !parent.exists()) { parent.mkdirs(); } StyleAssembler styleAssembler = new StyleAssembler(getLog()); styleAssembler.setVelocityComponent(velocity); if (!styles.isEmpty()) { getLog().info("Start merge styles to the: " + styleFile.getPath()); mergeResources(styleFile, styleAssembler, beforeStyleIncludes, afterStyleIncludes, styles); } Resource resource = new Resource(); resource.setDirectory(outputResourceDirectory.getPath()); project.addResource(resource); } Thread.currentThread().setContextClassLoader(oldClassLoader); } catch (Exception e) { getLog().error("Error generate resource", e); throw new MojoExecutionException(e.getMessage(), e); } } public void mergeResources(File assembly, ResourceAssembler assembler, List<String> beforeIncludes, List<String> afterIncludes, Collection<String> resources) { ResourcesGenerator styleGenerator = new ResourcesGenerator(getLog()); styleGenerator.setAssembler(assembler); styleGenerator.setIncludesAfter(afterIncludes); styleGenerator.setIncludesBefore(beforeIncludes); styleGenerator.setResources(resources); styleGenerator.setAssemblyFile(assembly); styleGenerator.doAssembly(); styleGenerator.writeToFile(); } protected Set<Artifact> resolveDependenciesArtifacts() throws Exception { ArtifactResolutionResult result = null; List<Dependency> dependencies = project.getDependencies(); Set<Artifact> artifacts = MavenMetadataSource.createArtifacts(factory, dependencies, null, null, project); artifacts.add(project.getArtifact()); result = resolver.resolveTransitively(artifacts, project.getArtifact(), Collections.EMPTY_LIST, localRepository, metadataSource); return result.getArtifacts(); } public ComponentsHandler findComponents(File webSourceDir, Map<String, Components> components, String[] includes, String[] excludes) throws Exception { if (includes == null) { includes = PluginUtils.DEFAULT_PROCESS_INCLUDES; } if (excludes == null) { excludes = new String[0]; } DirectoryScanner scanner = new DirectoryScanner(); scanner.setBasedir(webSourceDir); scanner.setIncludes(includes); scanner.setExcludes(excludes); scanner.addDefaultExcludes(); getLog().info("search *.xhtml files"); scanner.scan(); String[] collectedFiles = scanner.getIncludedFiles(); for (String collectedFile : collectedFiles) { getLog().info(collectedFile + " found"); } ComponentsHandler handler = new ComponentsHandler(getLog()); handler.setComponents(components); handler.setScriptIncludes(scriptIncludes); handler.setScriptExcludes(scriptExcludes); handler.setStyleIncludes(styleIncludes); handler.setStyleExcludes(styleExcludes); handler.setComponentIncludes(componentIncludes); handler.setComponentExcludes(componentExcludes); handler.setNamespaceIncludes(namespaceIncludes); handler.setNamespaceExcludes(namespaceExcludes); SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); saxParserFactory.setNamespaceAware(true); Log log = getLog(); for (String processFile : collectedFiles) { SAXParser saxParser = saxParserFactory.newSAXParser(); File file = new File(webSourceDir, processFile); if (file.exists()) { if (log.isDebugEnabled()) { log.debug("start process file: " + file.getPath()); } try { saxParser.parse(file, handler); } catch (Exception e) { if (log.isDebugEnabled()) { log.error("Error process file: " + file.getPath() + "\n" + e.getMessage(), e); } else { log.error("Error process file: " + file.getPath() + "\n" + e.getMessage()); } } } } return handler; } protected FileObject resolveArtifact(Artifact artifact) { FileObject jarFileObjects = null; if (artifact != null) { try { resolver.resolve(artifact, Collections.EMPTY_LIST, localRepository); if (getLog().isDebugEnabled()) { getLog().debug("artifact " + artifact.getFile().toURI() + " is resolved"); } } catch (ArtifactResolutionException e) { getLog().error( "Error with resolve artifact " + artifact.getFile().getPath() + "\n" + e.getMessage(), e); } catch (ArtifactNotFoundException e) { getLog().error("Not found artifact " + artifact.getFile().toURI() + "\n" + e.getMessage(), e); } File file = artifact.getFile(); try { FileSystemManager manager = VFS.getManager(); jarFileObjects = manager.resolveFile("jar:" + file.toURI()); } catch (FileSystemException e) { getLog().error("Error during processing file: " + file.toURI() + "\n" + e.getMessage(), e); } } return jarFileObjects; } public Digester createDigester() { // default digester for *.component-dependencies.xml return PluginUtils.createDefaultDigester(); } protected ClassLoader createClassLoader() throws Exception { ClassLoader classLoader = null; Set<Artifact> artifacts = resolveDependenciesArtifacts(); //create a new classloading space ClassWorld world = new ClassWorld(); //use the existing ContextClassLoader in a realm of the classloading space ClassRealm realm = world.newRealm("org.richfaces.cdk", Thread.currentThread().getContextClassLoader()); //create another realm for the app jars ClassRealm childRealm = realm.createChildRealm("jar"); for (Artifact jar : artifacts) { try { childRealm.addConstituent(jar.getFile().toURL()); } catch (MalformedURLException e) { getLog().error("Artifact url " + jar.getFile() + " is invalid"); } } // add project classes, scripts, styles etc ... List<Resource> compileClasspathElements = project.getCompileClasspathElements(); addResources(childRealm, compileClasspathElements); List<Resource> scripts = project.getScriptSourceRoots(); addResources(childRealm, scripts); List<Resource> resources = project.getResources(); addResources(childRealm, resources); childRealm.addConstituent(webSourceDirectory.toURI().toURL()); //make the child realm the ContextClassLoader classLoader = childRealm.getClassLoader(); return classLoader; } private void addResources(ClassRealm realm, List resources) { if (realm != null && resources != null) { for (Object path : resources) { URL url = null; String formatted = null; if (path instanceof String) { formatted = (String) path; } else if (path instanceof Resource) { formatted = ((Resource) path).getDirectory(); } if (formatted != null) { File file = new File(formatted); try { url = file.toURI().toURL(); } catch (MalformedURLException e) { getLog().error("Resource url " + file.getPath() + " is invalid"); } realm.addConstituent(url); } } } } }