package org.codehaus.mojo.runtime.builder; /* * Copyright (c) 2004, Codehaus.org * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is furnished to do * so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.maven.artifact.Artifact; import org.apache.maven.project.MavenProject; import org.codehaus.mojo.runtime.model.Runtime; import org.codehaus.mojo.runtime.model.io.xpp3.RuntimeXpp3Writer; import org.codehaus.mojo.runtime.util.JarMaker; import org.codehaus.plexus.util.FileUtils; /** * @author <a href="jesse.mcconnell@gmail.com">Jesse McConnell</a> * @version $Id$ */ public class MavenJarRuntimeBuilder extends AbstractMavenRuntimeBuilder { private File runtimeOutputDirectory; private File runtimeLibraryDirectory; private File runtimeExecutableDirectory; private File runtimeMetaDirectory; public void build( Runtime runtime, MavenProject project, File runtimeFile, File outputDirectory ) throws MavenRuntimeBuilderException { try { // prepare output directories initializeOutputDirectories( runtime, outputDirectory ); // add needed dependencies to the runtime object prepareRuntimeDependencies( runtime, project ); prepareRuntimeClasses(); prepareRuntimeExecutionDependencies( project ); // we need all the compiled classes into a jar of their own JarMaker projectJar = new JarMaker( runtimeLibraryDirectory, project.getArtifactId() + "-" + project.getVersion() + "-runtime.jar" ); projectJar.addDirectory( "**/**", "**/package.html,**/.svn/**", "", new File( project.getBuild().getDirectory() + File.separator + "classes" ) ); projectJar.create(); // make a dependency reference for this newly created jar runtime.getJar().addDependency( project.getGroupId() + ":" + project.getArtifactId() + ":" + project.getVersion() + "-runtime" ); // place the finalized runtime descriptor RuntimeXpp3Writer runtimeWriter = new RuntimeXpp3Writer(); FileWriter fw = new FileWriter( new File( runtimeMetaDirectory, "jar.runtime" ) ); runtimeWriter.write( fw, runtime ); fw.close(); // finally generate the end game jar JarMaker runtimeJar = new JarMaker( outputDirectory, project.getArtifactId() + "-runtime-" + project.getVersion() + ".jar" ); runtimeJar.addDirectory( "**/**", "**/package.html,**/.svn/**", "", runtimeOutputDirectory ); runtimeJar.addManifestEntry( "Main-Class", "org.codehaus.mojo.runtime.execute.RuntimeExecutor" ); runtimeJar.create(); } catch ( IOException ex ) { throw new MavenRuntimeBuilderException( "Exception while building the runtime", ex ); } } private void prepareRuntimeClasses() throws MavenRuntimeBuilderException { List runtimeModelObjects = new ArrayList(); runtimeModelObjects.add( "org/codehaus/mojo/runtime/model/Executable.class" ); runtimeModelObjects.add( "org/codehaus/mojo/runtime/model/Runtime.class" ); runtimeModelObjects.add( "org/codehaus/mojo/runtime/model/JarRuntime.class" ); runtimeModelObjects.add( "org/codehaus/mojo/runtime/model/RuntimeBase.class" ); runtimeModelObjects.add( "org/codehaus/mojo/runtime/model/ShellRuntime.class" ); runtimeModelObjects.add( "org/codehaus/mojo/runtime/model/io/xpp3/RuntimeXpp3Reader.class" ); runtimeModelObjects.add( "org/codehaus/mojo/runtime/model/io/xpp3/RuntimeXpp3Writer.class" ); runtimeModelObjects.add( "org/codehaus/plexus/util/xml/pull/XmlPullParserException.class" ); runtimeModelObjects.add( "org/codehaus/plexus/util/xml/pull/XmlPullParser.class" ); runtimeModelObjects.add( "org/codehaus/plexus/util/xml/pull/MXParser.class" ); runtimeModelObjects.add( "org/codehaus/mojo/runtime/execute/RuntimeClassLoader.class" ); runtimeModelObjects.add( "org/codehaus/mojo/runtime/execute/RuntimeExecutor.class" ); try { for ( Iterator i = runtimeModelObjects.iterator(); i.hasNext(); ) { String file = (String) i.next(); FileUtils.copyURLToFile( Thread.currentThread().getContextClassLoader().getResource( file ), new File( runtimeOutputDirectory + File.separator + file ) ); } } catch ( IOException e ) { throw new MavenRuntimeBuilderException( "unable to prepare runtime classes", e ); } } private void initializeOutputDirectories( Runtime runtime, File outputDirectory ) throws MavenRuntimeBuilderException { runtimeOutputDirectory = new File( outputDirectory, runtime.getJar().getId() ); runtimeLibraryDirectory = new File( runtimeOutputDirectory, "lib" ); runtimeExecutableDirectory = new File( runtimeOutputDirectory, "bin" ); runtimeMetaDirectory = new File( runtimeOutputDirectory, "META-INF/runtimes" ); mkdir( runtimeOutputDirectory ); mkdir( runtimeLibraryDirectory ); mkdir( runtimeExecutableDirectory ); mkdir( runtimeMetaDirectory ); } /** * put the dependencies that we are interested in using into the runtime object */ private void prepareRuntimeDependencies( Runtime runtime, MavenProject project ) { List artifactList = project.getRuntimeArtifacts(); List dependencies = runtime.getJar().getDependencies(); for ( Iterator i = artifactList.iterator(); i.hasNext(); ) { Artifact artifact = (Artifact) i.next(); String dependency = artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + artifact.getVersion(); // let preexisting dependencies take precedence if ( !dependencies.contains( dependency ) ) { runtime.getJar().addDependency( dependency ); } } } // copy libs to script dir private void prepareRuntimeExecutionDependencies( MavenProject project ) throws MavenRuntimeBuilderException { try { List classpathElements = project.getRuntimeClasspathElements(); for ( Iterator i = classpathElements.iterator(); i.hasNext(); ) { String element = (String) i.next(); if ( element.endsWith( ".jar" ) ) { FileUtils.copyFileToDirectory( (String) i.next(), runtimeLibraryDirectory.getAbsolutePath() ); } } } catch ( Exception e ) { throw new MavenRuntimeBuilderException( "unable to prepare runtime execution dependencies", e ); } } }