/* * #%L * carewebframework * %% * Copyright (C) 2008 - 2016 Regenstrief Institute, Inc. * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * This Source Code Form is also subject to the terms of the Health-Related * Additional Disclaimer of Warranty and Limitation of Liability available at * * http://www.carewebframework.org/licensing/disclaimer. * * #L% */ package org.carewebframework.maven.plugin.core; import java.io.File; import java.io.FileFilter; import java.util.Date; import java.util.List; import org.apache.commons.io.filefilter.WildcardFileFilter; import org.apache.commons.lang.StringUtils; import org.apache.maven.archiver.MavenArchiveConfiguration; import org.apache.maven.archiver.MavenArchiver; import org.apache.maven.artifact.Artifact; import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectHelper; import org.carewebframework.maven.plugin.processor.ResourceProcessor; import org.codehaus.plexus.archiver.jar.JarArchiver; import org.codehaus.plexus.util.FileUtils; import com.google.common.io.Files; /** * Base plugin. */ public abstract class BaseMojo extends AbstractMojo { @Component(role = org.codehaus.plexus.archiver.Archiver.class, hint = "jar") protected JarArchiver jarArchiver; @Component() protected MavenProjectHelper projectHelper; @Parameter(property = "project", readonly = true, required = true) protected MavenProject mavenProject; @Parameter(property = "session", readonly = true, required = true) protected MavenSession mavenSession; @Parameter(property = "plugin", readonly = true, required = true) private PluginDescriptor pluginDescriptor; @Parameter(property = "project.build.directory", required = true) protected File buildDirectory; @Parameter(property = "project.version", required = true) protected String projectVersion; @Parameter(property = "buildNumber", required = false) protected String buildNumber; @Parameter(property = "noclassifier", required = false) protected boolean noclassifier; @Parameter(property = "archive", alias = "archive", required = false) protected MavenArchiveConfiguration archiveConfig = new MavenArchiveConfiguration(); /** * Excluded files. */ @Parameter(property = "exclusions", required = false) private List<String> exclusions; /** * Additional resources to copy. */ @Parameter(property = "resources", required = false) private List<String> resources; /** * Webapp lib directory. */ @Parameter(defaultValue = "${project.build.directory}/${project.build.finalName}/WEB-INF/lib", readonly = true) private File webappLibDirectory; /** * If packaging is of type war, archives will be copied to destination dir: * ${project.build.directory}/${project.build.finalName}/WEB-INF/lib * <p> * <b>Note: phase must remain as prepare-package</b> * </p> */ @Parameter(property = "maven.carewebframework.mojo.warInclusion", defaultValue = "true", required = true) private boolean warInclusion; /** * Whether to fail build on error */ @Parameter(property = "maven.carewebframework.mojo.failOnError", defaultValue = "true", required = false) private boolean failOnError; private FileFilter exclusionFilter; protected File stagingDirectory; protected ConfigTemplate configTemplate; protected String classifier; protected String moduleBase; /** * Subclasses must call this method early in their execute method. * * @param classifier The output jar classifier. * @param moduleBase The base path for generated resources. * @throws MojoExecutionException Unspecified exception. */ protected void init(String classifier, String moduleBase) throws MojoExecutionException { this.classifier = classifier; this.moduleBase = moduleBase; stagingDirectory = new File(buildDirectory, classifier + "-staging"); configTemplate = new ConfigTemplate(classifier + "-spring.xml"); exclusionFilter = exclusions == null || exclusions.isEmpty() ? null : new WildcardFileFilter(exclusions); archiveConfig.setAddMavenDescriptor(false); } public MavenProject getMavenProject() { return mavenProject; } public List<String> getResources() { return resources; } public File getBuildDirectory() { return buildDirectory; } /** * Form a version string from the project version and build number. * * @return Version string. */ protected String getModuleVersion() { StringBuilder sb = new StringBuilder(); int pcs = 0; for (String pc : projectVersion.split("\\.")) { if (pcs++ > 3) { break; } else { appendVersionPiece(sb, pc); } } appendVersionPiece(sb, buildNumber); return sb.toString(); } /** * Helper method to add a configuration file entry. * * @param placeholder The insertion placeholder. * @param params Parameter list. */ public void addConfigEntry(String placeholder, String... params) { configTemplate.addEntry(placeholder, params); } /** * Append the version piece to the version # under construction. * * @param sb String builder receiving the version under construction. * @param pc The version piece to add. If null, it is ignored. If non-numeric, a value of "0" is * used. */ private void appendVersionPiece(StringBuilder sb, String pc) { if ((pc != null) && !pc.isEmpty()) { pc = pc.trim(); if (sb.length() > 0) { sb.append("."); } sb.append(StringUtils.isNumeric(pc) ? pc : "0"); } } /** * Creates a new file in the staging directory. Ensures that all folders in the path are also * created. * * @param entryName Entry name to create. * @param modTime Modification timestamp for the new entry. If 0, defaults to the current time. * @return the new file */ public File newStagingFile(String entryName, long modTime) { File file = new File(stagingDirectory, entryName); if (modTime != 0) { file.setLastModified(modTime); } file.getParentFile().mkdirs(); return file; } /** * Returns true if the specified file is in the exclusion list. * * @param fileName Name of file to check. * @return True if the file is to be excluded. */ public boolean isExcluded(String fileName) { return isExcluded(new File(fileName)); } /** * Returns true if the specified file is in the exclusion list. * * @param file File instance to check. * @return True if the file is to be excluded. */ public boolean isExcluded(File file) { return exclusionFilter != null && exclusionFilter.accept(file); } /** * If "failOnError" is enabled, throws a MojoExecutionException. Otherwise, logs the exception * and resumes execution. * * @param msg The exception message. * @param e The original exceptions. * @throws MojoExecutionException Thrown exception. */ public void throwMojoException(String msg, Throwable e) throws MojoExecutionException { if (failOnError) { throw new MojoExecutionException(msg, e); } else { getLog().error(msg, e); } } /** * Assembles the archive file. Optionally, copies to the war application directory if the * packaging type is "war". * * @throws Exception Unspecified exception. */ protected void assembleArchive() throws Exception { getLog().info("Assembling " + classifier + " archive"); if (resources != null && !resources.isEmpty()) { getLog().info("Copying additional resources."); new ResourceProcessor(this, moduleBase, resources).transform(); } if (configTemplate != null) { getLog().info("Creating config file."); configTemplate.addEntry("info", pluginDescriptor.getName(), pluginDescriptor.getVersion(), new Date().toString()); configTemplate.createFile(stagingDirectory); } try { File archive = createArchive(); if ("war".equalsIgnoreCase(mavenProject.getPackaging()) && this.warInclusion) { webappLibDirectory.mkdirs(); File webappLibArchive = new File(this.webappLibDirectory, archive.getName()); Files.copy(archive, webappLibArchive); } } catch (Exception e) { throw new RuntimeException("Exception occurred assembling archive.", e); } } /** * Creates the archive from data in the staging directory. * * @return The archive file. * @throws Exception Unspecified exception. */ private File createArchive() throws Exception { getLog().info("Creating archive."); Artifact artifact = mavenProject.getArtifact(); String clsfr = noclassifier ? "" : ("-" + classifier); String archiveName = artifact.getArtifactId() + "-" + artifact.getVersion() + clsfr + ".jar"; File jarFile = new File(mavenProject.getBuild().getDirectory(), archiveName); MavenArchiver archiver = new MavenArchiver(); jarArchiver.addDirectory(stagingDirectory); archiver.setArchiver(jarArchiver); archiver.setOutputFile(jarFile); archiver.createArchive(mavenSession, mavenProject, archiveConfig); if (noclassifier) { artifact.setFile(jarFile); } else { projectHelper.attachArtifact(mavenProject, jarFile, classifier); } FileUtils.deleteDirectory(stagingDirectory); return jarFile; } }