package net.jangaroo.jooc.mvnplugin; import org.apache.maven.archiver.MavenArchiver; import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectHelper; import org.apache.maven.archiver.MavenArchiveConfiguration; import org.codehaus.plexus.archiver.ArchiverException; import org.codehaus.plexus.archiver.jar.JarArchiver; import org.codehaus.plexus.archiver.jar.Manifest; import org.codehaus.plexus.archiver.jar.ManifestException; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.util.Set; /** * Creates the jangaroo archive and attaches them to the project.<br> * The jangaroo archive is created by zipping the <code>outputDirectory</code> * (defaults to target/classes). * <p/> * The <code>package</code> goal is executed in the <code>package</code> phase of the jangaroo lifecycle. * * @goal package * @phase package * @threadSafe */ @SuppressWarnings({"ResultOfMethodCallIgnored", "UnusedDeclaration", "UnusedPrivateField"}) public class PackageMojo extends AbstractMojo { /** * The maven project. * * @parameter expression="${project}" * @required * @readonly */ private MavenProject project; /** * Destination directory for the Maven artifacts (*.jar). Default is <code> * ${project.build.directory}</code> * * @parameter expression="${project.build.directory}" */ private File targetDir; /** * @component */ private MavenProjectHelper projectHelper; /** * List of files to exclude. Specified as fileset patterns. * * @parameter */ private String[] excludes; /** * The name of the JAR file (without extension) generated as this module's artifact. Defaults to ${project.artifactId} * * @parameter default-value="${project.build.finalName}" * " */ private String finalName; /** * Plexus archiver. * * @component role="org.codehaus.plexus.archiver.Archiver" role-hint="jar" * @required */ private JarArchiver archiver; /** * @deprecated use <code>defaultManifestFile</code> * @parameter */ private File manifest; /** * The archive configuration to use. * See <a href="http://maven.apache.org/shared/maven-archiver/index.html">Maven Archiver Reference</a>. * * @parameter */ private MavenArchiveConfiguration archive = new MavenArchiveConfiguration(); /** * Path to the default MANIFEST file to use. It will be used if * <code>useDefaultManifestFile</code> is set to <code>true</code>. * * @parameter default-value="${project.build.outputDirectory}/META-INF/MANIFEST.MF" * @required * @readonly */ private File defaultManifestFile; /** * Set this to <code>true</code> to enable the use of the <code>defaultManifestFile</code>. * * @parameter expression="${jar.useDefaultManifestFile}" default-value="false" */ private boolean useDefaultManifestFile; /** * Location of files to be packaged, which are all files placed in the other goal's outputDirectory. * Defaults to ${project.build.outputDirectory} * * @parameter expression="${project.build.outputDirectory}" */ private File outputDirectory; /** * This parameter specifies the path and name of the file containing the JavaScript code to execute when this * module is used, relative to the outputDirectory. * If this file is not created through copying the corresponding resource, and the jsClassesFile exists, * a file containing the code to load the concatenated Jangaroo classes file is created. * * @parameter expression="META-INF/resources/joo/${project.artifactId}.module.js" */ private String moduleJsFile; /** * This parameter specifies the path and name of the output file containing all * compiled classes, relative to the outputDirectory. * * @parameter expression="META-INF/resources/joo/${project.groupId}.${project.artifactId}.classes.js" */ private String moduleClassesJsFile; public void execute() throws MojoExecutionException { File jarFile = new File(targetDir, finalName + "." + Types.JAVASCRIPT_EXTENSION); MavenArchiver mavenArchiver = new MavenArchiver(); mavenArchiver.setArchiver(archiver); mavenArchiver.setOutputFile(jarFile); try { if (archive.getManifestFile() == null) { if (useDefaultManifestFile && defaultManifestFile.exists()) { getLog().info( "Adding existing MANIFEST to archive. Found under: " + defaultManifestFile.getPath() ); archive.setManifestFile( defaultManifestFile ); } else if (manifest != null) { archive.setManifestFile(manifest); } else { archive.setManifestFile(createDefaultManifest(project)); } } if (outputDirectory.exists()) { mavenArchiver.getArchiver().addDirectory(outputDirectory); if (!getModuleJsFile().exists() && new File(outputDirectory, moduleClassesJsFile).exists()) { createDefaultModuleJsFile(); } } String groupId = project.getGroupId(); String artifactId = project.getArtifactId(); mavenArchiver.getArchiver().addFile(project.getFile(), "META-INF/maven/" + groupId + "/" + artifactId + "/pom.xml"); mavenArchiver.createArchive(project, archive); } catch (Exception e) { // NOSONAR throw new MojoExecutionException("Failed to create the javascript archive", e); } project.getArtifact().setFile(jarFile); } private File getModuleJsFile() { return new File(outputDirectory, moduleJsFile); } private void createDefaultModuleJsFile() throws IOException { File jsFile = getModuleJsFile(); File moduleJsDir = jsFile.getParentFile(); if (moduleJsDir != null) { if (moduleJsDir.mkdirs()) { getLog().debug("created module output directory " + moduleJsDir); } } getLog().info("Creating Jangaroo module classes loader script '" + jsFile.getAbsolutePath() + "'."); OutputStreamWriter writer = null; try { writer = new OutputStreamWriter(new FileOutputStream(jsFile), "UTF-8"); writer.write("joo.loadModule(\"" + project.getGroupId() + "\",\"" + project.getArtifactId() + "\");\n"); } finally { if (writer != null) { writer.close(); } } } private static File createDefaultManifest(MavenProject project) throws ManifestException, IOException, ArchiverException { Manifest manifest = new Manifest(); Manifest.Attribute attr = new Manifest.Attribute("Created-By", "Apache Maven"); manifest.addConfiguredAttribute(attr); attr = new Manifest.Attribute("Implementation-Title", project.getName()); manifest.addConfiguredAttribute(attr); attr = new Manifest.Attribute("Implementation-Version", project.getVersion()); manifest.addConfiguredAttribute(attr); attr = new Manifest.Attribute("Implementation-Vendor-Id", project.getGroupId()); manifest.addConfiguredAttribute(attr); if (project.getOrganization() != null) { String vendor = project.getOrganization().getName(); attr = new Manifest.Attribute("Implementation-Vendor", vendor); manifest.addConfiguredAttribute(attr); } attr = new Manifest.Attribute("Built-By", System.getProperty("user.name")); manifest.addConfiguredAttribute(attr); attr = new Manifest.Attribute("Class-Path", jangarooDependencies(project)); manifest.addConfiguredAttribute(attr); File mf = File.createTempFile("maven", ".mf"); mf.deleteOnExit(); PrintWriter writer = null; try { writer = new PrintWriter(new FileWriter(mf)); manifest.write(writer); } finally { if (writer != null) { writer.close(); } } return mf; } @SuppressWarnings({"unchecked"}) private static String jangarooDependencies(MavenProject project) { StringBuilder sb = new StringBuilder(); Set<Artifact> dependencyArtifacts = project.getDependencyArtifacts(); for (Artifact artifact : dependencyArtifacts) { if ("jar".equals(artifact.getType())) { sb.append(artifact.getArtifactId()).append("-").append(artifact.getVersion()).append(".jar "); } } return sb.toString(); } }