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();
}
}