initial checkin
This commit is contained in:
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
# Maven
|
||||
target
|
||||
pom.xml.versionsBackup
|
||||
|
||||
# Eclipse
|
||||
.settings
|
||||
.project
|
||||
.classpath
|
||||
|
117
pom.xml
Normal file
117
pom.xml
Normal file
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.inteligr8.alfresco</groupId>
|
||||
<artifactId>maven-amp-plugin</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>maven-plugin</packaging>
|
||||
|
||||
<name>A Maven plugin to generate AMP files</name>
|
||||
<description>Generate Alfresco Module Packages (AMP) files in a way simialr to WAR files</description>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>brian.long</id>
|
||||
<name>Brian Long</name>
|
||||
<email>brian@inteligr8.com</email>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>1.7</maven.compiler.source>
|
||||
<maven.compiler.target>1.7</maven.compiler.target>
|
||||
<maven.version>3.6.3</maven.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.aether</groupId>
|
||||
<artifactId>aether-util</artifactId>
|
||||
<version>1.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-plugin-api</artifactId>
|
||||
<version>${maven.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.plugin-tools</groupId>
|
||||
<artifactId>maven-plugin-annotations</artifactId>
|
||||
<version>3.6.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-core</artifactId>
|
||||
<version>${maven.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.plugin-testing</groupId>
|
||||
<artifactId>maven-plugin-testing-harness</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-compat</artifactId>
|
||||
<version>${maven.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-plugin-plugin</artifactId>
|
||||
<version>3.6.0</version>
|
||||
<configuration>
|
||||
<goalPrefix>amp</goalPrefix>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>mojo-descriptor</id>
|
||||
<goals>
|
||||
<goal>descriptor</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>help-goal</id>
|
||||
<goals>
|
||||
<goal>helpmojo</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>inteligr8-release</id>
|
||||
<name>Inteligr8 Releases</name>
|
||||
<url>http://repos.yateslong.us/nexus/repository/inteligr8-public</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
|
||||
</project>
|
||||
|
323
src/main/java/com/inteligr8/alfresco/amp/AmpMojo.java
Normal file
323
src/main/java/com/inteligr8/alfresco/amp/AmpMojo.java
Normal file
@@ -0,0 +1,323 @@
|
||||
package com.inteligr8.alfresco.amp;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.maven.execution.MavenSession;
|
||||
import org.apache.maven.model.Exclusion;
|
||||
import org.apache.maven.model.FileSet;
|
||||
import org.apache.maven.model.Resource;
|
||||
import org.apache.maven.plugin.AbstractMojo;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.plugins.annotations.LifecyclePhase;
|
||||
import org.apache.maven.plugins.annotations.Mojo;
|
||||
import org.apache.maven.plugins.annotations.Parameter;
|
||||
import org.apache.maven.plugins.annotations.ResolutionScope;
|
||||
import org.apache.maven.project.DefaultDependencyResolutionRequest;
|
||||
import org.apache.maven.project.DependencyResolutionException;
|
||||
import org.apache.maven.project.DependencyResolutionRequest;
|
||||
import org.apache.maven.project.DependencyResolutionResult;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.apache.maven.project.ProjectDependenciesResolver;
|
||||
import org.codehaus.plexus.component.annotations.Component;
|
||||
import org.codehaus.plexus.component.annotations.Requirement;
|
||||
import org.codehaus.plexus.util.FileUtils;
|
||||
import org.codehaus.plexus.util.IOUtil;
|
||||
import org.eclipse.aether.graph.Dependency;
|
||||
import org.eclipse.aether.util.filter.DependencyFilterUtils;
|
||||
import org.eclipse.aether.util.filter.ExclusionsDependencyFilter;
|
||||
import org.eclipse.aether.util.filter.ScopeDependencyFilter;
|
||||
|
||||
@Mojo( name = "amp", defaultPhase = LifecyclePhase.PACKAGE, threadSafe = true,
|
||||
requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME )
|
||||
@Component( role = org.apache.maven.plugin.Mojo.class )
|
||||
public class AmpMojo extends AbstractMojo {
|
||||
|
||||
private final Pattern modulePropertiesPattern = Pattern.compile("^alfresco/module/[^/]+/module\\.properties$");
|
||||
private final int streamBufferSize = 16384;
|
||||
|
||||
@Parameter( defaultValue = "${project}", readonly = true )
|
||||
protected MavenProject project;
|
||||
|
||||
@Parameter( defaultValue = "${session}", readonly = true )
|
||||
protected MavenSession session;
|
||||
|
||||
@Requirement
|
||||
private ProjectDependenciesResolver resolver;
|
||||
|
||||
@Parameter( property = "outputFile", required = true, defaultValue = "${project.build.directory}/${project.artifactId}-${project.version}.amp" )
|
||||
protected String outputAmpFile;
|
||||
|
||||
@Parameter( property = "moduleFile", required = true, defaultValue = "${project.build.directory}/${project.build.finalName}.${project.artifact.type}" )
|
||||
protected String moduleJarFile;
|
||||
|
||||
@Parameter( property = "modulePropertyFile", required = false )
|
||||
protected String modulePropFile;
|
||||
|
||||
@Parameter( property = "resources", required = false )
|
||||
protected List<Resource> resources;
|
||||
|
||||
@Parameter( property = "dependencyIncludeScopes", required = true, defaultValue = "compile,runtime" )
|
||||
protected String includeScopes;
|
||||
|
||||
@Parameter( property = "dependencyExclusions", required = false )
|
||||
protected List<Exclusion> excludeDependencies;
|
||||
|
||||
@Parameter( property = "lib", required = false )
|
||||
protected List<FileSet> libDirectories;
|
||||
|
||||
@Parameter( property = "charset", required = true, defaultValue = "utf-8" )
|
||||
protected String charsetName;
|
||||
|
||||
@Parameter( property = "skip", required = true, defaultValue = "false" )
|
||||
protected boolean skip;
|
||||
|
||||
public void execute() throws MojoExecutionException {
|
||||
if (this.skip) {
|
||||
this.getLog().debug("Skipped AMP packaging");
|
||||
return;
|
||||
}
|
||||
this.getLog().debug("Executing AMP packaging");
|
||||
|
||||
this.normalize();
|
||||
|
||||
File ampFile = this.getOutputFile();
|
||||
this.getLog().debug("Writing AMP file: " + ampFile.getAbsolutePath());
|
||||
|
||||
try {
|
||||
FileOutputStream fostream = new FileOutputStream(ampFile, false);
|
||||
BufferedOutputStream bostream = new BufferedOutputStream(fostream, this.streamBufferSize);
|
||||
ZipOutputStream zstream = new ZipOutputStream(bostream, Charset.forName(this.charsetName));
|
||||
try {
|
||||
this.zip(zstream);
|
||||
|
||||
zstream.finish();
|
||||
} finally {
|
||||
zstream.close();
|
||||
}
|
||||
} catch (DependencyResolutionException dre) {
|
||||
throw new MojoExecutionException("The dependencies could not be properly resolved", dre);
|
||||
} catch (IOException ie) {
|
||||
throw new MojoExecutionException("An I/O issue occurred", ie);
|
||||
}
|
||||
|
||||
this.getLog().debug("Wrote AMP file: " + ampFile.length());
|
||||
}
|
||||
|
||||
private void normalize() {
|
||||
this.outputAmpFile = StringUtils.trimToNull(this.outputAmpFile);
|
||||
this.moduleJarFile = StringUtils.trimToNull(this.moduleJarFile);
|
||||
this.modulePropFile = StringUtils.trimToNull(this.modulePropFile);
|
||||
if (this.resources == null)
|
||||
this.resources = Collections.emptyList();
|
||||
this.includeScopes = this.includeScopes.trim();
|
||||
if (this.libDirectories == null)
|
||||
this.libDirectories = Collections.emptyList();
|
||||
|
||||
this.getLog().debug("Normalized parameters");
|
||||
}
|
||||
|
||||
private File getOutputFile() {
|
||||
File ampFile = new File(this.outputAmpFile);
|
||||
if (ampFile.exists())
|
||||
ampFile.delete();
|
||||
return ampFile;
|
||||
}
|
||||
|
||||
private File getModuleFile() throws MojoExecutionException {
|
||||
File jarFile = new File(this.moduleJarFile);
|
||||
if (!jarFile.exists())
|
||||
throw new MojoExecutionException("The module JAR file does not exist: " + this.moduleJarFile);
|
||||
return jarFile;
|
||||
}
|
||||
|
||||
private File getModulePropertyFile() throws MojoExecutionException {
|
||||
File propFile = null;
|
||||
if (this.modulePropFile != null) {
|
||||
propFile = new File(this.modulePropFile);
|
||||
} else {
|
||||
String outputDirectory = this.project.getBuild().getOutputDirectory();
|
||||
File modulesDirectory = new File(outputDirectory, "alfresco/module");
|
||||
if (!modulesDirectory.exists() || !modulesDirectory.isDirectory())
|
||||
throw new MojoExecutionException("The module.properties file could not be found: 'alfresco/module' path does not exist");
|
||||
|
||||
File moduleDirectory = new File(modulesDirectory, this.project.getGroupId() + "." + this.project.getArtifactId());
|
||||
if (!moduleDirectory.exists())
|
||||
moduleDirectory = new File(modulesDirectory, this.project.getArtifactId());
|
||||
if (!moduleDirectory.exists()) {
|
||||
File[] files = modulesDirectory.listFiles();
|
||||
if (files.length > 0) {
|
||||
moduleDirectory = files[0];
|
||||
if (!moduleDirectory.exists())
|
||||
throw new MojoExecutionException("The module.properties file could not be found: 'alfresco/module' path does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
propFile = new File(moduleDirectory, "module.properties");
|
||||
}
|
||||
|
||||
if (!propFile.exists())
|
||||
throw new MojoExecutionException("The module.properties file does not exist: " + propFile.getAbsolutePath());
|
||||
return propFile;
|
||||
}
|
||||
|
||||
private void zip(ZipOutputStream zstream) throws IOException, MojoExecutionException, DependencyResolutionException {
|
||||
for (Resource resource : this.resources)
|
||||
this.zipResource(zstream, resource);
|
||||
|
||||
File jarFile = this.getModuleFile();
|
||||
this.zipFile(zstream, jarFile, "lib");
|
||||
|
||||
File propFile = this.getModulePropertyFile();
|
||||
this.zipFile(zstream, propFile, "");
|
||||
|
||||
Collection<Dependency> deps = this.getDependencies();
|
||||
if (deps.isEmpty()) {
|
||||
this.getLog().info("Zipped 0 dependencies");
|
||||
} else {
|
||||
for (Dependency dependency : deps) {
|
||||
File file = dependency.getArtifact().getFile();
|
||||
if (this.isAlfrescoModule(file)) {
|
||||
this.getLog().info("Not packaging JAR; detected as Alfresco JAR Module: " + dependency.getArtifact().getArtifactId());
|
||||
} else {
|
||||
this.zipFile(zstream, file, "lib");
|
||||
}
|
||||
}
|
||||
if (this.getLog().isInfoEnabled())
|
||||
this.getLog().info("Zipped " + deps.size() + " dependencies");
|
||||
}
|
||||
|
||||
for (FileSet fileset : this.libDirectories)
|
||||
this.zipFileset(zstream, fileset, "lib");
|
||||
}
|
||||
|
||||
private List<String> getExclusions() {
|
||||
List<String> exclusions = new ArrayList<>(this.excludeDependencies.size());
|
||||
for (Exclusion exclusion : this.excludeDependencies)
|
||||
exclusions.add(exclusion.getGroupId() + ":" + exclusion.getArtifactId());
|
||||
return exclusions;
|
||||
}
|
||||
|
||||
private Collection<Dependency> getDependencies() throws DependencyResolutionException {
|
||||
String[] includeScopes = StringUtils.split(this.includeScopes, ",");
|
||||
|
||||
ScopeDependencyFilter scopeFilter = new ScopeDependencyFilter(Arrays.asList(includeScopes), new ArrayList<String>(0));
|
||||
ExclusionsDependencyFilter exclusionFilter = new ExclusionsDependencyFilter(this.getExclusions());
|
||||
|
||||
DependencyResolutionRequest request = new DefaultDependencyResolutionRequest(this.project, this.session.getRepositorySession());
|
||||
request.setResolutionFilter(DependencyFilterUtils.andFilter(scopeFilter, exclusionFilter));
|
||||
|
||||
DependencyResolutionResult result = this.resolver.resolve(request);
|
||||
return result.getResolvedDependencies();
|
||||
}
|
||||
|
||||
private void zipResource(ZipOutputStream zstream, Resource resource) throws MojoExecutionException, IOException {
|
||||
String baseZipPath = resource.getTargetPath();
|
||||
if (baseZipPath == null)
|
||||
baseZipPath = "";
|
||||
else if (!baseZipPath.endsWith("/"))
|
||||
baseZipPath += "/";
|
||||
this.zipFileset(zstream, resource, baseZipPath);
|
||||
}
|
||||
|
||||
private void zipFileset(ZipOutputStream zstream, FileSet fileset, String targetPath) throws MojoExecutionException, IOException {
|
||||
targetPath = StringUtils.trimToEmpty(targetPath);
|
||||
if (targetPath.length() > 0 && !targetPath.endsWith("/"))
|
||||
targetPath += "/";
|
||||
|
||||
File directory = new File(this.project.getBasedir(), fileset.getDirectory());
|
||||
if (!directory.exists())
|
||||
return;
|
||||
if (!directory.isDirectory())
|
||||
throw new MojoExecutionException("The fileset 'directory' must be a directory: " + fileset.getDirectory());
|
||||
|
||||
String includes = StringUtils.join(fileset.getIncludes(), ",");
|
||||
String excludes = StringUtils.join(fileset.getExcludes(), ",");
|
||||
List<String> filenames = FileUtils.getFileNames(directory, includes, excludes, false, true);
|
||||
|
||||
if (this.getLog().isDebugEnabled())
|
||||
this.getLog().debug("Zipping files in: " + fileset.getDirectory());
|
||||
for (String filename : filenames) {
|
||||
if (this.getLog().isDebugEnabled())
|
||||
this.getLog().debug("Zipping file: " + filename);
|
||||
|
||||
zstream.putNextEntry(new ZipEntry(filename));
|
||||
|
||||
File file = new File(directory, filename);
|
||||
FileReader freader = new FileReader(file);
|
||||
try {
|
||||
IOUtil.copy(freader, zstream);
|
||||
} finally {
|
||||
freader.close();
|
||||
}
|
||||
|
||||
zstream.closeEntry();
|
||||
}
|
||||
|
||||
if (this.getLog().isInfoEnabled())
|
||||
this.getLog().info("Zipped " + filenames.size() + " files: " + fileset.getDirectory());
|
||||
}
|
||||
|
||||
private void zipFile(ZipOutputStream zstream, File file, String targetPath) throws IOException {
|
||||
targetPath = StringUtils.trimToEmpty(targetPath);
|
||||
if (targetPath.length() > 0 && !targetPath.endsWith("/"))
|
||||
targetPath += "/";
|
||||
|
||||
if (this.getLog().isDebugEnabled())
|
||||
this.getLog().debug("Zipping file: " + file.toString());
|
||||
|
||||
zstream.putNextEntry(new ZipEntry(targetPath + file.getName()));
|
||||
|
||||
FileReader freader = new FileReader(file);
|
||||
try {
|
||||
IOUtil.copy(freader, zstream);
|
||||
} finally {
|
||||
freader.close();
|
||||
}
|
||||
|
||||
zstream.closeEntry();
|
||||
}
|
||||
|
||||
private boolean isAlfrescoModule(File file) throws IOException {
|
||||
FileInputStream fistream = new FileInputStream(file);
|
||||
BufferedInputStream bistream = new BufferedInputStream(fistream, this.streamBufferSize);
|
||||
ZipInputStream zstream = new ZipInputStream(bistream, Charset.forName(this.charsetName));
|
||||
try {
|
||||
ZipEntry zentry = zstream.getNextEntry();
|
||||
while (zentry != null) {
|
||||
this.getLog().debug("dep entry: " + zentry.getName());
|
||||
try {
|
||||
Matcher modPropsMatcher = this.modulePropertiesPattern.matcher(zentry.getName());
|
||||
if (modPropsMatcher.find())
|
||||
return true;
|
||||
} finally {
|
||||
zstream.closeEntry();
|
||||
}
|
||||
|
||||
zentry = zstream.getNextEntry();
|
||||
}
|
||||
} finally {
|
||||
zstream.close();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user