org.wisdom.maven.mojos.WebJarPackager Maven / Gradle / Ivy
Show all versions of wisdom-maven-plugin Show documentation
/*
* #%L
* Wisdom-Framework
* %%
* Copyright (C) 2013 - 2014 Wisdom Framework
* %%
* 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.
* #L%
*/
package org.wisdom.maven.mojos;
import org.apache.commons.io.FileUtils;
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.shared.model.fileset.FileSet;
import org.codehaus.plexus.archiver.jar.JarArchiver;
import org.codehaus.plexus.archiver.jar.Manifest;
import org.codehaus.plexus.archiver.jar.ManifestException;
import org.wisdom.maven.Constants;
import org.wisdom.maven.WatchingException;
import org.wisdom.maven.utils.BuildConstants;
import org.wisdom.maven.utils.PlexusLoggerWrapper;
import org.wisdom.maven.utils.WatcherUtils;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
/**
* This mojo is responsible for the creation of the webjar containing the internal asset of the project. The created
* webjar is conform to the webjar specification.
*
* The webjar artifact is generated using the "webjar" classifier.
*
* In watch mode, only the webjar is re-created on every resource change.
*/
@Mojo(name = "package-webjar", threadSafe = false,
requiresDependencyResolution = ResolutionScope.COMPILE,
requiresProject = true,
defaultPhase = LifecyclePhase.PACKAGE)
public class WebJarPackager extends AbstractWisdomWatcherMojo {
/**
* The root of the webjar in the jar file.
*/
protected static final String ROOT = "META-INF/resources/webjars/";
/**
* WebJar configuration. Let you define the file set to include, the webjar name (it uses the artifact id by
* default), the webjar version (it uses the project's version by default), and the classifier.
*/
@Parameter
WebJar webjar;
/**
* Flag to enabled or disabled the webjar packaging. By default it's disabled.
*/
@Parameter(defaultValue = "false")
boolean packageWebJar;
/**
* Whether or not it should copy the created webjar to the wisdom directory in watch mode. Enabled by default.
*/
@Parameter(defaultValue = "true")
boolean deployWebJarToWisdom;
@Override
public void execute() throws MojoExecutionException {
if (!enabled()) {
removeFromWatching();
return;
}
FileSet set = new FileSet();
set.setDirectory(getInternalAssetOutputDirectory().getAbsolutePath());
if (webjar == null) {
webjar = new WebJar(project.getArtifactId(), project.getVersion(), "webjar", set);
} else {
if (webjar.getFileset() == null) {
webjar.setFileset(set);
} else if (webjar.getFileset().getDirectory() == null) {
getLog().info("No directory define in the webjar fileset - use the AssetOutputDirectory");
webjar.getFileset().setDirectory(getInternalAssetOutputDirectory().getAbsolutePath());
}
if (webjar.getName() == null) {
webjar.setName(project.getArtifactId());
}
if (webjar.getVersion() == null) {
webjar.setVersion(project.getVersion());
}
if (webjar.getClassifier() == null) {
webjar.setClassifier("webjar");
}
}
try {
File out = process();
if (out != null) {
projectHelper.attachArtifact(project, out, webjar.getClassifier());
if (deployWebJarToWisdom) {
copyToDestination(out);
}
}
} catch (Exception e) {
throw new MojoExecutionException("Failure while building the webjar", e);
}
}
protected void copyToDestination(File output) throws IOException {
// Copy the built file to the application directory.
// We use getWisdomRootDirectory to deploy to the output wisdom (in remote watch mode).
File dest = new File(new File(getWisdomRootDirectory(), Constants.APPLICATION_DIR), webjar.getOutputFileName());
// Write a small notice about the copy
getLog().info("Copying " + dest.getName() + " to " + dest.getAbsolutePath());
FileUtils.copyFile(output, dest, true);
}
private File process() throws IOException, ManifestException {
getLog().info("Building webjar for " + project.getArtifactId());
File output = new File(buildDirectory, webjar.getOutputFileName());
FileUtils.deleteQuietly(output);
// Compute the set of selected files:
Collection selected = webjar.getSelectedFiles();
if (selected.isEmpty()) {
getLog().warn("No file selected in the webjar - skipping creation");
return null;
}
String root = computeRoot();
FileUtils.deleteQuietly(output);
// Web jar are jar file, so use the Plexus Archiver.
JarArchiver archiver = new JarArchiver();
archiver.enableLogging(new PlexusLoggerWrapper(getLog()));
String base = webjar.getFileset().getDirectory();
for (File file : selected) {
final String destFileName = root + "/" + file.getAbsolutePath().substring(base.length() + 1);
getLog().debug(file.getName() + " => " + destFileName);
archiver.addFile(file, destFileName);
}
// Extend the manifest with webjar data - this is not required by the webjar specification
Manifest manifest = Manifest.getDefaultManifest();
manifest.getMainSection().addConfiguredAttribute(new Manifest.Attribute("Webjar-Name", webjar.getName()));
manifest.getMainSection().addConfiguredAttribute(new Manifest.Attribute("Webjar-Version", webjar.getVersion()));
manifest.getMainSection().addConfiguredAttribute(new Manifest.Attribute("Created-By", "Wisdom Framework " +
BuildConstants.get("WISDOM_PLUGIN_VERSION")));
archiver.addConfiguredManifest(manifest);
archiver.setDestFile(output);
archiver.createArchive();
return output;
}
private String computeRoot() {
return ROOT + webjar.getName() + "/" + webjar.getVersion();
}
/**
* Checks whether or not the packaging is enabled or not.
*
* @return {@code true} if it is, {@code false} otherwise
*/
protected boolean enabled() {
return packageWebJar || webjar != null;
}
/**
* Checks whether the given file is managed by the current watcher. Notice that implementation must not check
* for the existence of the file as this method is also called for deleted files.
*
* @param file is the file.
* @return {@literal true} if the watcher is interested in being notified on an event
* attached to the given file,
* {@literal false} otherwise.
*/
@Override
public boolean accept(File file) {
return WatcherUtils.isInDirectory(file, getInternalAssetsDirectory());
}
/**
* Notifies the watcher that a new file is created.
*
* @param file is the file.
* @return {@literal false} if the pipeline processing must be interrupted for this event. Most watchers should
* return {@literal true} to let other watchers be notified.
* @throws org.wisdom.maven.WatchingException if the watcher failed to process the given file.
*/
@Override
public boolean fileCreated(File file) throws WatchingException {
try {
File output = process();
if (deployWebJarToWisdom) {
// Copy the webjar to the right location
copyToDestination(output);
}
} catch (Exception e) {
throw new WatchingException("Failure while building the webjar", e);
}
return true;
}
/**
* Notifies the watcher that a file has been modified.
*
* @param file is the file.
* @return {@literal false} if the pipeline processing must be interrupted for this event. Most watchers should
* returns {@literal true} to let other watchers to be notified.
* @throws org.wisdom.maven.WatchingException if the watcher failed to process the given file.
*/
@Override
public boolean fileUpdated(File file) throws WatchingException {
return fileCreated(file);
}
/**
* Notifies the watcher that a file was deleted.
*
* @param file the file
* @return {@literal false} if the pipeline processing must be interrupted for this event. Most watchers should
* return {@literal true} to let other watchers be notified.
* @throws org.wisdom.maven.WatchingException if the watcher failed to process the given file.
*/
@Override
public boolean fileDeleted(File file) throws WatchingException {
return fileCreated(file);
}
}