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

com.github.jlgrock.javascriptframework.sourcearchive.AbstractArchiveMojo Maven / Gradle / Ivy

package com.github.jlgrock.javascriptframework.sourcearchive;

import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;
import org.apache.maven.archiver.MavenArchiveConfiguration;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.assembly.AssemblerConfigurationSource;
import org.apache.maven.plugin.assembly.InvalidAssemblerConfigurationException;
import org.apache.maven.plugin.assembly.archive.ArchiveCreationException;
import org.apache.maven.plugin.assembly.archive.AssemblyArchiver;
import org.apache.maven.plugin.assembly.format.AssemblyFormattingException;
import org.apache.maven.plugin.assembly.io.AssemblyReadException;
import org.apache.maven.plugin.assembly.io.AssemblyReader;
import org.apache.maven.plugin.assembly.model.Assembly;
import org.apache.maven.plugin.assembly.utils.AssemblyFormatUtils;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;
import org.apache.maven.shared.filtering.MavenFileFilter;
import org.codehaus.plexus.configuration.PlexusConfiguration;

import com.github.jlgrock.javascriptframework.mavenutils.io.DirectoryIO;
import com.github.jlgrock.javascriptframework.mavenutils.io.ResourceIO;
import com.github.jlgrock.javascriptframework.mavenutils.logging.MojoLogAppender;

/**
 * Essentially the same as the Assembly Plugin Mojo, with a convenience function
 * to have the src assembly xml files set up for you already. Unfortunately
 * there is no way to extend from one plugin space to another within the plexus
 * system, so I copied the entire Mojo.
 * 
 * This is just to help automate and minimize the amount of code in the poms.
 * 
 * @threadSafe
 */
public abstract class AbstractArchiveMojo extends AbstractMojo implements
		AssemblerConfigurationSource {

	/**
	 * The Logger.
	 */
	static final Logger LOGGER = Logger.getLogger(AbstractArchiveMojo.class);

	/**
	 * Location to get the assembly descriptor.
	 * 
	 * @parameter default-value=
	 *            "${project.build.directory}${file.separator}assemblyDescriptor${file.separator}assembly.xml"
	 * @required
	 */
	protected String assemblyDescriptorLocation;

	/**
	 * Remove target directories before starting work.
	 * 
	 * @throws IOException 
	 */
	protected void cleanup() throws IOException {
		File assemblyDesc = new File(assemblyDescriptorLocation);
		if (assemblyDesc.exists()) {
			if (assemblyDesc.isDirectory()) {
				DirectoryIO.recursivelyDeleteDirectory(assemblyDesc);
			} else {
				assemblyDesc.delete();
			}
		}
	}

	/**
	 * Copy the descriptor over to do the type of archiving required.
	 * 
	 * @throws IOException 
	 */
	protected final void copyDescriptorResource() throws IOException {
		LOGGER.info("copying default descriptor to \""
				+ assemblyDescriptorLocation + "\"");
		if (assemblyDescriptorLocation == null) {
			LOGGER.error("assemblyDescriptorLocation cannot be null");
		}
		File descLoc = new File(assemblyDescriptorLocation);
		ResourceIO.copyResource(getDescriptorResourceName(), descLoc);
	}

	/**
	 * Accessor to the descriptor resource name that will be defined in children
	 * objects.
	 * 
	 * @return the descriptor resource name
	 */
	protected abstract String getDescriptorResourceName();

	/**
	 * Flag allowing one or more executions of the assembly plugin to be
	 * configured as skipped for a particular build. This makes the assembly
	 * plugin more controllable from profiles.
	 * 
	 * @parameter expression="${assembly.skipAssembly}" default-value="false"
	 */
	private boolean skipAssembly;

	/**
	 * If this flag is set, everything up to the call to
	 * Archiver.createArchive() will be executed.
	 * 
	 * @parameter expression="${assembly.dryRun}" default-value="false"
	 */
	private boolean dryRun;

	/**
	 * If this flag is set, the ".dir" suffix will be suppressed in the output
	 * directory name when using assembly/format == 'dir' and other formats that
	 * begin with 'dir'. 
* NOTE: Since 2.2-beta-3, the default-value for this is true, NOT * false as it used to be. * * @parameter default-value="true" */ private boolean ignoreDirFormatExtensions; /** * Local Maven repository where artifacts are cached during the build * process. * * @parameter default-value="${localRepository}" * @required * @readonly */ private ArtifactRepository localRepository; /** * @parameter default-value="${project.remoteArtifactRepositories}" * @required * @readonly */ private List remoteRepositories; /** * Contains the full list of projects in the reactor. * * @parameter default-value="${reactorProjects}" * @required * @readonly */ private List reactorProjects; /** * The output directory of the assembled distribution file. * * @parameter default-value="${project.build.directory}" * @required */ private File outputDirectory; /** * The filename of the assembled distribution file. * * @parameter default-value="${project.build.finalName}-src" * @required */ private String finalName; /** * Directory to unpack JARs into if needed. * * @parameter default-value="${project.build.directory}/assembly/work" * @required */ private File workDirectory; /** * This is the artifact classifier to be used for the resultant assembly * artifact. Normally, you would use the assembly-id instead of specifying * this here. * * @parameter expression="${classifier}" * @deprecated Please use the Assembly's id for classifier instead */ @Deprecated @SuppressWarnings("unused") private String classifier; /** * A list of descriptor files to generate from. * * @parameter */ private String[] descriptors; /** * A list of references to assembly descriptors available on the plugin's * classpath. The default classpath includes these built-in descriptors: * bin, jar-with-dependencies, src, * and project. You can add others by adding dependencies to * the plugin. * * @parameter */ private String[] descriptorRefs; /** * Directory to scan for descriptor files in. NOTE: This may not work * correctly with assembly components. * * @parameter */ private File descriptorSourceDirectory; /** * This is the base directory from which archive files are created. This * base directory pre-pended to any <directory> * specifications in the assembly descriptor. This is an optional parameter. * * @parameter */ private File archiveBaseDirectory; /** * Predefined Assembly Descriptor Id's. You can select bin, * jar-with-dependencies, or src. * * @parameter expression="${descriptorId}" * @deprecated Please use descriptorRefs instead */ @Deprecated protected String descriptorId; /** * Assembly XML Descriptor file. This must be the path to your customized * descriptor file. * * @parameter expression="${descriptor}" * @deprecated Please use descriptors instead */ @Deprecated protected String descriptor; /** * Sets the TarArchiver behavior on file paths with more than 100 characters * length. Valid values are: "warn" (default), "fail", "truncate", "gnu", or * "omit". * * @parameter expression="${assembly.tarLongFileMode}" default-value="warn" */ private String tarLongFileMode; /** * Base directory of the project. * * @parameter default-value="${project.basedir}" * @required * @readonly */ private File basedir; /** * Maven ProjectHelper. * * @component */ private MavenProjectHelper projectHelper; /** * Maven shared filtering utility. * * @component */ private MavenFileFilter mavenFileFilter; /** * The Maven Session Object. * * @parameter default-value="${session}" * @required * @readonly */ private MavenSession mavenSession; /** * Temporary directory that contain the files to be assembled. * * @parameter default-value="${project.build.directory}/archive-tmp" * @required * @readonly */ private File tempRoot; /** * Directory for site generated. * * @parameter default-value="${project.reporting.outputDirectory}" * @readonly */ private File siteDirectory; /** * Set to true to include the site generated by site:site goal. * * @parameter expression="${includeSite}" default-value="false" * @deprecated Please set this variable in the assembly descriptor instead */ @Deprecated private boolean includeSite; /** * Set to false to exclude the assembly id from the assembly final name. * * @parameter expression="${assembly.appendAssemblyId}" * default-value="false" */ protected boolean appendAssemblyId; /** * Set to true in order to not fail when a descriptor is missing. * * @parameter expression="${assembly.ignoreMissingDescriptor}" * default-value="false" */ protected boolean ignoreMissingDescriptor; /** * This is a set of instructions to the archive builder, especially for * building .jar files. It enables you to specify a Manifest file for the * jar, in addition to other options. * * @parameter */ private MavenArchiveConfiguration archive; /** * @parameter */ protected List filters; /** * Controls whether the assembly plugin tries to attach the resulting * assembly to the project. * * @parameter expression="${assembly.attach}" default-value="true" * @since 2.2-beta-1 */ private boolean attach; /** * @component */ private AssemblyArchiver assemblyArchiver; /** * @component */ private AssemblyReader assemblyReader; /** * Allows additional configuration options that are specific to a particular * type of archive format. This is intended to capture an XML configuration * that will be used to reflectively setup the options on the archiver * instance.
* For instance, to direct an assembly with the "ear" format to use a * particular deployment descriptor, you should specify the following for * the archiverConfig value in your plugin configuration:
* *
	 * <appxml>${project.basedir}/somepath/app.xml</appxml>
	 * 
* * @parameter * @since 2.2-beta-3 */ private PlexusConfiguration archiverConfig; /** * This will cause the assembly to run only at the top of a given module * tree. That is, run in the project contained in the same folder where the * mvn execution was launched. * * @parameter expression="${assembly.runOnlyAtExecutionRoot}" * default-value="false" * @since 2.2-beta-4 */ private boolean runOnlyAtExecutionRoot; /** * This will cause the assembly to only update an existing archive, if it * exists. * * @parameter expression="${assembly.updatOnly}" default-value="false" * @since 2.2 */ private boolean updateOnly; /** *

* will use the jvm chmod, this is available for user and all level group * level will be ignored. *

* * @parameter expression="${assembly.useJvmChmod}" default-value="false" * @since 2.2 */ private boolean useJvmChmod; /** *

* Set to true in order to avoid all chmod calls. *

* *

* NOTE: This will cause the assembly plugin to DISREGARD all * fileMode/directoryMode settings in the assembly descriptor, and all file * permissions in unpacked dependencies! *

* * @parameter expression="${assembly.ignorePermissions}" * default-value="false" * @since 2.2 */ private boolean ignorePermissions; /** * Create the binary distribution. * * @throws MojoExecutionException * @throws MojoFailureException * */ public void execute() throws MojoExecutionException, MojoFailureException { MojoLogAppender.beginLogging(this); try { // TODO this should only really be extending the // SimpleAssemblyPlugin, but // Maven/Plexus doesn't support extending a separate plug-in // // **********************************************************/ // CODE ADDED TO ASSEMBLY PLUGIN // **********************************************************/ LOGGER.info("initial cleanup"); cleanup(); LOGGER.info("copying descriptor resource for assembly."); copyDescriptorResource(); String[] descLocs = { assemblyDescriptorLocation }; setDescriptors(descLocs); LOGGER.info("executing assembly."); // this is a convenience mojo anyways, so I have automatically // stopped the // appending of id on the source code bundles this.setAppendAssemblyId(false); // **********************************************************/ // END CODE ADDED TO ASSEMBLY PLUGIN // **********************************************************/ if (skipAssembly) { LOGGER.info("Assemblies have been skipped per configuration of the skipAssembly parameter."); return; } // run only at the execution root. if (runOnlyAtExecutionRoot && !isThisTheExecutionRoot()) { LOGGER.info("Skipping the assembly in this project because it's not the Execution Root"); return; } List assemblies; try { assemblies = assemblyReader.readAssemblies(this); } catch (final AssemblyReadException e) { throw new MojoExecutionException("Error reading assemblies: " + e.getMessage(), e); } catch (final InvalidAssemblerConfigurationException e) { throw new MojoFailureException(assemblyReader, e.getMessage(), "Mojo configuration is invalid: " + e.getMessage()); } // TODO: include dependencies marked for distribution under certain // formats // TODO: how, might we plug this into an installer, such as NSIS? boolean warnedAboutMainProjectArtifact = false; for (final Iterator assemblyIterator = assemblies .iterator(); assemblyIterator.hasNext();) { final Assembly assembly = assemblyIterator.next(); try { final String fullName = AssemblyFormatUtils .getDistributionName(assembly, this); for (final String format : assembly.getFormats()) { final File destFile = assemblyArchiver.createArchive( assembly, fullName, format, this); final MavenProject project = getProject(); final String classifier = getClassifier(); final String type = project.getArtifact().getType(); if (attach && destFile.isFile()) { if (isAssemblyIdAppended()) { projectHelper.attachArtifact(project, format, assembly.getId(), destFile); } else if (classifier != null) { projectHelper.attachArtifact(project, format, classifier, destFile); } else if (!"pom".equals(type) && format.equals(type)) { if (!warnedAboutMainProjectArtifact) { final StringBuffer message = new StringBuffer(); message.append("Configuration options: 'appendAssemblyId' is set to false, and 'classifier' is missing."); message.append( "\nInstead of attaching the assembly file: ") .append(destFile) .append(", it will become the file for main project artifact."); message.append("\nNOTE: If multiple descriptors or descriptor-formats are provided for this project, the value of this file will be non-deterministic!"); LOGGER.warn(message); warnedAboutMainProjectArtifact = true; } final File existingFile = project.getArtifact() .getFile(); if ((existingFile != null) && existingFile.exists()) { LOGGER.warn("Replacing pre-existing project main-artifact file: " + existingFile + "\nwith assembly file: " + destFile); } project.getArtifact().setFile(destFile); } else { projectHelper.attachArtifact(project, format, null, destFile); } } else if (attach) { LOGGER.warn("Assembly file: " + destFile + " is not a regular file (it may be a directory). It cannot be attached to the project build for installation or deployment."); } } // **********************************************************/ // CODE ADDED TO ASSEMBLY PLUGIN // **********************************************************/ } catch (final ArchiveCreationException e) { throw new MojoExecutionException( "Failed to create assembly: " + e.getMessage(), e); } catch (final AssemblyFormattingException e) { throw new MojoExecutionException( "Failed to create assembly: " + e.getMessage(), e); } catch (final InvalidAssemblerConfigurationException e) { throw new MojoFailureException(assembly, "Assembly is incorrectly configured: " + assembly.getId(), "Assembly: " + assembly.getId() + " is not configured correctly: " + e.getMessage()); } } } catch (Exception e) { LOGGER.error( "Full Source Archive has encountered an error. Please check stack trace for details. : " + e.getMessage(), e); throw new MojoExecutionException(e.getMessage(), e); } finally { MojoLogAppender.endLogging(); } } /** * Returns true if the current project is located at the Execution Root * Directory (where mvn was launched). * * @return execution root */ protected boolean isThisTheExecutionRoot() { LOGGER.debug("Root Folder:" + mavenSession.getExecutionRootDirectory()); LOGGER.debug("Current Folder:" + basedir); final boolean result = mavenSession.getExecutionRootDirectory() .equalsIgnoreCase(basedir.toString()); if (result) { LOGGER.debug("This is the execution root."); } else { LOGGER.debug("This is NOT the execution root."); } return result; } /** * Accessor. * * @return assembly archiver */ protected AssemblyArchiver getAssemblyArchiver() { return assemblyArchiver; } /** * Accessor. * * @return assembly reader */ protected AssemblyReader getAssemblyReader() { return assemblyReader; } /** * Accessor. * * @return basedir */ public File getBasedir() { return basedir; } /** * {@inheritDoc} * * @deprecated This has been replaced by {@link #getDescriptors()} */ @Deprecated public String getDescriptor() { return descriptor; } /** * {@inheritDoc} * * @deprecated This has been replaced by {@link #getDescriptorReferences()} */ @Deprecated public String getDescriptorId() { return descriptorId; } /** * Accessor. * * @return descriptor ref */ public String[] getDescriptorReferences() { return descriptorRefs; } /** * Accessor. * * @return x */ public File getDescriptorSourceDirectory() { return descriptorSourceDirectory; } /** * Accessor. * * @return x */ public String[] getDescriptors() { return descriptors; } /** * Accessor. * * @return x */ public abstract MavenProject getProject(); /** * Accessor. * * @return x */ public File getSiteDirectory() { return siteDirectory; } /** * Accessor. * * @return x */ public boolean isSiteIncluded() { return includeSite; } /** * Accessor. * * @return x */ public String getFinalName() { return finalName; } /** * Accessor. * * @return x */ public boolean isAssemblyIdAppended() { return appendAssemblyId; } /** * Accessor. * * @return x */ public String getTarLongFileMode() { return tarLongFileMode; } /** * Accessor. * * @return x */ public File getOutputDirectory() { return outputDirectory; } /** * Accessor. * * @return x */ public MavenArchiveConfiguration getJarArchiveConfiguration() { return archive; } /** * Accessor. * * @return x */ public File getWorkingDirectory() { return workDirectory; } /** * Accessor. * * @return x */ public ArtifactRepository getLocalRepository() { return localRepository; } /** * Accessor. * * @return x */ public File getTemporaryRootDirectory() { return tempRoot; } /** * Accessor. * * @return x */ public File getArchiveBaseDirectory() { return archiveBaseDirectory; } /** * Accessor. * * @return x */ public List getFilters() { if (filters == null) { filters = getProject().getBuild().getFilters(); if (filters == null) { filters = Collections.emptyList(); } } return filters; } /** * Accessor. * * @return x */ public List getReactorProjects() { return reactorProjects; } /** * Accessor. * * @return x */ public String getClassifier() { // TODO Auto-generated method stub return null; } /** * Accessor. * * @return x */ protected MavenProjectHelper getProjectHelper() { return projectHelper; } /** * Mutator. * * @param appendAssemblyId */ public void setAppendAssemblyId(final boolean appendAssemblyId) { this.appendAssemblyId = appendAssemblyId; } /** * Mutator. * * @param archive */ public void setArchive(final MavenArchiveConfiguration archive) { this.archive = archive; } /** * Mutator. * * @param archiveBaseDirectory */ public void setArchiveBaseDirectory(final File archiveBaseDirectory) { this.archiveBaseDirectory = archiveBaseDirectory; } /** * Mutator. * * @param assemblyArchiver */ public void setAssemblyArchiver(final AssemblyArchiver assemblyArchiver) { this.assemblyArchiver = assemblyArchiver; } /** * Mutator. * * @param assemblyReader */ public void setAssemblyReader(final AssemblyReader assemblyReader) { this.assemblyReader = assemblyReader; } /** * Mutator. * * @param basedir */ public void setBasedir(final File basedir) { this.basedir = basedir; } /** * Mutator. * * @param classifier */ public void setClassifier(final String classifier) { this.classifier = classifier; } /** * {@inheritDoc} * * @deprecated This has been replaced by {@link #setDescriptors(String[])} */ @Deprecated public void setDescriptor(final String descriptor) { this.descriptor = descriptor; } /** * {@inheritDoc} * * @deprecated This has been replaced by * {@link #setDescriptorRefs(String[])} */ @Deprecated public void setDescriptorId(final String descriptorId) { this.descriptorId = descriptorId; } /** * Mutator. * * @param descriptorRefs */ public void setDescriptorRefs(final String[] descriptorRefs) { this.descriptorRefs = descriptorRefs; } /** * Mutator. * * @param descriptors */ public void setDescriptors(final String[] descriptors) { this.descriptors = descriptors; } /** * Mutator. * * @param descriptorSourceDirectory */ public void setDescriptorSourceDirectory( final File descriptorSourceDirectory) { this.descriptorSourceDirectory = descriptorSourceDirectory; } /** * Mutator. * * @param filters */ public void setFilters(final List filters) { this.filters = filters; } /** * Mutator. * * @param finalName */ public void setFinalName(final String finalName) { this.finalName = finalName; } /** * Mutator. * * @param includeSite */ public void setIncludeSite(final boolean includeSite) { this.includeSite = includeSite; } /** * Mutator. * * @param localRepository */ public void setLocalRepository(final ArtifactRepository localRepository) { this.localRepository = localRepository; } /** * Mutator. * * @param outputDirectory */ public void setOutputDirectory(final File outputDirectory) { this.outputDirectory = outputDirectory; } /** * Mutator. * * @param projectHelper */ public void setProjectHelper(final MavenProjectHelper projectHelper) { this.projectHelper = projectHelper; } /** * Mutator. * * @param reactorProjects */ public void setReactorProjects(final List reactorProjects) { this.reactorProjects = reactorProjects; } /** * Mutator. * * @param siteDirectory */ public void setSiteDirectory(final File siteDirectory) { this.siteDirectory = siteDirectory; } /** * Mutator. * * @param tarLongFileMode */ public void setTarLongFileMode(final String tarLongFileMode) { this.tarLongFileMode = tarLongFileMode; } /** * Mutator. * * @param tempRoot */ public void setTempRoot(final File tempRoot) { this.tempRoot = tempRoot; } /** * Mutator. * * @param workDirectory */ public void setWorkDirectory(final File workDirectory) { this.workDirectory = workDirectory; } /** * Accessor. * * @return x */ public List getRemoteRepositories() { return remoteRepositories; } /** * Accessor. * * @return x */ public boolean isDryRun() { return dryRun; } /** * Accessor. * * @return x */ public boolean isIgnoreDirFormatExtensions() { return ignoreDirFormatExtensions; } /** * Accessor. * * @return x */ public boolean isIgnoreMissingDescriptor() { return ignoreMissingDescriptor; } /** * Accessor. * * @param ignoreMissingDescriptor */ public void setIgnoreMissingDescriptor(final boolean ignoreMissingDescriptor) { this.ignoreMissingDescriptor = ignoreMissingDescriptor; } /** * Accessor. * * @return x */ public MavenSession getMavenSession() { return mavenSession; } /** * Accessor. * * @return x */ public String getArchiverConfig() { return archiverConfig == null ? null : archiverConfig.toString(); } /** * Accessor. * * @return x */ public MavenFileFilter getMavenFileFilter() { return mavenFileFilter; } /** * Accessor. * * @return x */ public boolean isUpdateOnly() { return updateOnly; } /** * Accessor. * * @return x */ public boolean isUseJvmChmod() { return useJvmChmod; } /** * Accessor. * * @return x */ public boolean isIgnorePermissions() { return ignorePermissions; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy