All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.pyx4me.maven.j2me.PackageMojo Maven / Gradle / Ivy

There is a newer version: 2.0.4
Show newest version
/**
 * Pyx4me framework
 * Copyright (C) 2006-2007 pyx4.com.
 * 
 * @author vlads
 * @version $Id: PackageMojo.java 1589 2007-12-06 20:07:11Z vlads $
 */
package com.pyx4me.maven.j2me;

import java.io.File;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.maven.archiver.MavenArchiveConfiguration;
import org.apache.maven.archiver.MavenArchiver;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.model.Dependency;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProjectHelper;
import org.codehaus.plexus.archiver.jar.JarArchiver;

/**
 * The j2me:package task is an wrapper for Jar task that handles JAD files
 * correctly. It also allows for obfuscation and preverification of the
 * generated file.
 * 
 * @author vlads
 * 
 * @goal package
 * @phase package
 * @description Create JAR and JAD files for j2me application
 */

public class PackageMojo extends AbstractJadWtkMojo {

	/**
	 * The directory containing generated classes.
	 * 
	 * @parameter expression="${project.build.outputDirectory}"
	 * @required
	 * @readonly
	 */
	private File classesDirectory;

	/**
	 * Specifies whether or not to attach the JAR and JAD artifacts to the
	 * project
	 * 
	 * @parameter expression="${j2me.attach}" default-value="true"
	 */
	private boolean attach = true;

	/**
	 * Specifies whether or not to attach the JAR and JAD test artifacts to the
	 * project
	 * 
	 * @parameter default-value="false"
	 */
	private boolean testAttach = false;

	/**
	 * Specifies whether or not execute ClassPreprocessor on created JAR.
	 * 
	 * @parameter expression="${j2me.preprocess}" default-value="false"
	 */
	private boolean preprocess = false;

	/**
	 * Reads configuration options from the given jour xml config file.
	 * 
	 * @parameter
	 */
	private String jourConfig;

	/**
	 * Reads configuration options from the given jour xml config file when
	 * processing "test" artifact.
	 * 
	 * @parameter
	 */
	private String jourConfigTest;

	/**
	 * Specifies whether or not execute ProGuard on created JAR.
	 * 
	 * @parameter expression="${j2me.obfuscate}" default-value="true"
	 */
	private boolean proguard = true;

	/**
	 * Specifies not to obfuscate the input class files.
	 * 
	 * @parameter default-value="true"
	 */
	private boolean obfuscate;

	/**
	 * Use ProGuard preverification instead of WTK. (ProGuard option
	 * -microedition)
	 * 
	 * @parameter default-value="false"
	 */
	private boolean proguardPreverify = false;

	/**
	 * Apply ProGuard classpathentry Filters to input jar. e.g.
	 * !**.gif,!**/awt/**,!**/tests/**'
	 * 
	 * @parameter
	 */
	protected String inFilter;

	/**
	 * Bundle project dependency to resulting jar. Specifies list of artifact
	 * inclusions and exclusions. By default all provided and system scope
	 * dependency are excluded from final jar all other included.
	 * 
	 * @parameter
	 */
	protected Assembly assembly;

	/**
	 * ProGuard configuration options
	 * 
	 * @parameter
	 */
	private ProguardOptions proguardOptions;

	/**
	 * Additional ProGuard configuration options when processing test package.
	 * 
	 * @parameter
	 */
	private ProguardOptions proguardTestOptions;

	/**
	 * Recursively reads ProGuard configuration options from the given file
	 * filename
	 * 
	 * @parameter default-value="${basedir}/proguard.conf"
	 */
	private File proguardInclude;

	/**
	 * Recursively reads ProGuard configuration options from the given file
	 * filename when processing test pakage.
	 * 
	 * @parameter default-value="${basedir}/proguard-test.conf"
	 */
	private File proguardTestInclude;

	/**
	 * Copy custom properties from the JAD into the Manifest.
	 * 
	 * @parameter default-value="true"
	 */
	private boolean copyJadAttributesToManifest = true;

	/**
	 * The maven archive configuration to use.
	 * 
	 * @parameter
	 */
	protected MavenArchiveConfiguration archive = new MavenArchiveConfiguration();

	/**
	 * The Jar archiver.
	 * 
	 * @parameter expression="${component.org.codehaus.plexus.archiver.Archiver#jar}"
	 * @required
	 */
	private JarArchiver jarArchiver;

	/**
	 * @component
	 */
	private MavenProjectHelper projectHelper;

	public void execute() throws MojoExecutionException, MojoFailureException {

		if ("pom".equals(packaging)) {
			getLog().info("NOT applicable for packaging: \'" + packaging + "\'.");
			return;
		}

		executePackage(classifier, false);
		if (test) {
			executePackage(testClassifier, true);
		}
	}

	public void executePackage(String packageClassifier, boolean isTest) throws MojoExecutionException,
			MojoFailureException {

		File jarFile = getJarFile(packageClassifier);
		getLog().info("Building j2me " + packageClassifier + " package: " + jarFile);

		getLog().debug(((!this.useWtkLibs) ? "NOT " : "") + "Using WTK Libraries");

		if (getLog().isDebugEnabled()) {
			Set artifacts = mavenProject.getArtifacts();
			for (Iterator i = artifacts.iterator(); i.hasNext();) {
				Artifact artifact = (Artifact) i.next();
				getLog().debug("artifact:" + artifact.getArtifactId() + " " + artifact.getScope());
			}
			artifacts = mavenProject.getDependencyArtifacts();
			for (Iterator i = artifacts.iterator(); i.hasNext();) {
				Artifact artifact = (Artifact) i.next();
				getLog().debug("dependency artifact:" + artifact.getArtifactId() + " " + artifact.getScope());
			}

			List dependancy = mavenProject.getCompileArtifacts();
			for (Iterator i = dependancy.iterator(); i.hasNext();) {
				Artifact artifact = (Artifact) i.next();
				getLog().debug("compile artifact:" + artifact.getArtifactId() + " " + artifact.getScope());
			}
			dependancy = mavenProject.getTestArtifacts();
			for (Iterator i = dependancy.iterator(); i.hasNext();) {
				Artifact artifact = (Artifact) i.next();
				getLog().debug("test artifact:" + artifact.getArtifactId() + " " + artifact.getScope());
			}
			dependancy = mavenProject.getTestDependencies();
			for (Iterator i = dependancy.iterator(); i.hasNext();) {
				Dependency dependency = (Dependency) i.next();
				getLog().debug("test dependancy:" + dependency.getArtifactId() + " " + dependency.getScope());
			}
		}

		performJarPackaging(packageClassifier, isTest);

		File preprocessed = null;

		if (preprocess) {
			String config = isTest ? jourConfigTest : jourConfig;
			if (config != null) {

				// This will fix ProGuard: The output is up to date
				File baseFile = new File(jarFile.toString() + "_instrument_base.jar");
				if (baseFile.exists()) {
					if (!baseFile.delete()) {
						throw new MojoFailureException("Can't delete " + baseFile);
					}
				}
				if (!jarFile.renameTo(baseFile)) {
					throw new MojoFailureException("Can't rename " + jarFile);
				}

				preprocessed = PreprocessMojo.executeClassPreprocessor(config, baseFile, "iclasses"
						+ (isTest ? "-test" : ""), this);
			} else {
				getLog().info("No Preprocessor defined for j2me " + packageClassifier + " package");
			}
		}

		boolean noPreverify = "false".equals(System.getProperty("j2me.preverify"));
		if (proguard || proguardPreverify) {
			if (preprocessed == null) {
				preprocessed = jarFile;
			}
			ProGuardMojo.executeProGuard(preprocessed, jarFile, proguardInclude, obfuscate, (noPreverify ? false
					: proguardPreverify), this, isTest, proguardTestInclude, inFilter, proguardOptions,
					proguardTestOptions);
		} else if (preprocessed != null) {
			throw new MojoFailureException("Unsupported configuration, should use proguard after preprocessing");
			// TODO updateJarFile(jarFile, preprocessed);
		}

		if ((!proguardPreverify) && (!noPreverify)) {
			WtkPreverifyMojo.executeWtkPreverifyTask(jarFile, this);
		}

		WtkJadMojo.executeCreateJad(this, packageClassifier, isTest);

		if ((attach && (!isTest)) || (isTest && testAttach)) {
			projectHelper.attachArtifact(mavenProject, "jad", packageClassifier, getJadFile(packageClassifier));
		}

	}

	private void populateManifestEntries(boolean isTest) {
		populateJadAttributes();
		Map entries = archive.getManifestEntries();
		// Copy required Jad Attributes
		if (!entries.containsKey(JAD_ATR_PROFILE)) {
			entries.put(JAD_ATR_PROFILE, jadAttributes.get(JAD_ATR_PROFILE));
		}
		if (!entries.containsKey(JAD_ATR_CONFIGURATION)) {
			entries.put(JAD_ATR_CONFIGURATION, jadAttributes.get(JAD_ATR_CONFIGURATION));
		}
		if ((!entries.containsKey(JAD_ATR_MIDLET_ICON)) && (jadAttributes.containsKey(JAD_ATR_MIDLET_ICON))) {
			entries.put(JAD_ATR_MIDLET_ICON, jadAttributes.get(JAD_ATR_MIDLET_ICON));
		}

		if (!entries.containsKey(JAD_ATR_MIDLET_NAME)) {
			entries.put(JAD_ATR_MIDLET_NAME, midletName);
		}
		if (!entries.containsKey(JAD_ATR_MIDLET_VENDOR)) {
			entries.put(JAD_ATR_MIDLET_VENDOR, midletVendor);
		}
		if (!entries.containsKey(JAD_ATR_MIDLET_VERSION)) {
			entries.put(JAD_ATR_MIDLET_VERSION, properMidletVersion());
		} else {
			entries.put(JAD_ATR_MIDLET_VERSION, properMidletVersion((String) entries.get(JAD_ATR_MIDLET_VERSION)));
		}

		if (midlets != null) {
			int cnt = 1;
			for (int i = 0; i < midlets.length; i++) {
				MIDlet m = midlets[i];
				if (m.test && (!isTest)) {
					continue;
				}
				entries.put("MIDlet-" + cnt, m.name + ", " + m.icon + ", " + m.cls);
				cnt++;
			}
		}

		// Copy other Jad Attributes
		if (copyJadAttributesToManifest) {
			for (Iterator i = jadAttributes.entrySet().iterator(); i.hasNext();) {
				Map.Entry jadEntry = (Map.Entry) i.next();
				if (!entries.containsKey(jadEntry.getKey())) {
					entries.put(jadEntry.getKey(), jadEntry.getValue());
				}
			}
		}

		// "Archiver-Version: Plexus Archiver" is causing problem for Mororola
		if (!entries.containsKey("Archiver-Version")) {
			// TODO get Maven version
			entries.put("Archiver-Version", "1.0");
		}

		if (getLog().isDebugEnabled()) {
			for (Iterator i = entries.entrySet().iterator(); i.hasNext();) {
				Map.Entry jarEntry = (Map.Entry) i.next();
				getLog().debug("ManifestEntry | " + jarEntry.getKey() + ": " + jarEntry.getValue());
			}
		}
	}

	private void performJarPackaging(String packageClassifier, boolean isTest) throws MojoExecutionException,
			MojoFailureException {

		populateManifestEntries(isTest);

		MavenArchiver archiver = new MavenArchiver();

		try {
			getLog().debug("jarPackaging " + (isTest ? "test" : "regular"));

			// Add classes to Package
			getLog().debug("merge classesDirectory: " + classesDirectory);
			jarArchiver.addDirectory(classesDirectory);
			if (isTest) {
				getLog().debug("merge TestOutputDirectory: " + mavenProject.getBuild().getTestOutputDirectory());
				jarArchiver.addDirectory(new File(mavenProject.getBuild().getTestOutputDirectory()));
			}
			archiver.setArchiver(jarArchiver);

			archiver.setOutputFile(getJarFile(packageClassifier));

			archive.setAddMavenDescriptor(false);

			List dependancy;
			if (!isTest) {
				dependancy = mavenProject.getCompileArtifacts();
			} else {
				dependancy = mavenProject.getTestArtifacts();
			}
			for (Iterator i = dependancy.iterator(); i.hasNext();) {
				Artifact artifact = (Artifact) i.next();
				if (Artifact.SCOPE_PROVIDED.equals(artifact.getScope())) {
					if (!isInclusion(artifact)) {
						continue;
					}
				}
				if (Artifact.SCOPE_SYSTEM.equals(artifact.getScope())) {
					if (!isInclusion(artifact)) {
						continue;
					}
				}
				if ((!isTest) && (Artifact.SCOPE_TEST.equals(artifact.getScope()))) {
					continue;
				}
				if ("junit".equals(artifact.getArtifactId()) && "junit".equals(artifact.getGroupId())) {
					if (!isInclusion(artifact)) {
						continue;
					}
				}

				if (isExclusion(artifact)) {
					continue;
				}

				File file = getClasspathElement(artifact, mavenProject);
				if (file.isDirectory()) {
					getLog().info("merge project: " + artifact.getArtifactId() + " " + file);
					jarArchiver.addDirectory(file);
				} else {
					getLog().info("merge artifact: " + artifact.getArtifactId());
					jarArchiver.addArchivedFileSet(file);
				}
			}

			// create archive

			archiver.createArchive(mavenProject, archive);
		} catch (Throwable e) {
			getLog().error("Unable to create jar " + e.getMessage(), e);
			throw new MojoExecutionException("Unable to create jar", e);
		}

		if ((attach && (!isTest)) || (isTest && testAttach)) {
			projectHelper.attachArtifact(mavenProject, "jar", packageClassifier, getJarFile(packageClassifier));
		}
	}

	private boolean isExclusion(Artifact artifact) {
		if ((assembly == null) || (assembly.exclusions == null)) {
			return false;
		}
		for (Iterator iter = assembly.exclusions.iterator(); iter.hasNext();) {
			Exclusion excl = (Exclusion) iter.next();
			if (excl.match(artifact)) {
				return true;
			}
		}
		return false;
	}

	private boolean isInclusion(Artifact artifact) {
		if ((assembly == null) || (assembly.inclusions == null)) {
			return false;
		}
		for (Iterator iter = assembly.inclusions.iterator(); iter.hasNext();) {
			Inclusion incl = (Inclusion) iter.next();
			if (incl.match(artifact)) {
				return true;
			}
		}
		return false;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy