blob: 4a77afd419ae60dda4cb8948190b8e9e975999d5 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
package org.apache.karaf.tooling.features;
import org.apache.karaf.deployer.kar.KarArtifactInstaller;
import org.apache.karaf.features.BundleInfo;
import org.apache.karaf.features.ConfigFileInfo;
import org.apache.karaf.features.Feature;
import org.apache.karaf.features.internal.RepositoryImpl;
import org.apache.maven.archiver.MavenArchiveConfiguration;
import org.apache.maven.archiver.MavenArchiver;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.codehaus.plexus.archiver.jar.JarArchiver;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* Assembles and creates a KAR archive.
*
* @goal create-kar
* @phase package
* @requiresDependencyResolution runtime
* @inheritByDefault true
* @description Assemble and create a KAR archive from a feature.xml file
*/
public class CreateKarMojo extends MojoSupport {
/**
* The Maven archive configuration to use.
* <p/>
* See <a href="http://maven.apache.org/ref/current/maven-archiver/apidocs/org/apache/maven/archiver/MavenArchiveConfiguration.html">the Javadocs for MavenArchiveConfiguration</a>
*
* @parameter
*/
private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();
/**
* The Jar archiver.
*
* @component role="org.codehaus.plexus.archiver.Archiver" roleHint="jar"
* @required
* @readonly
*/
private JarArchiver jarArchiver = null;
/**
* Directory containing the generated archive.
*
* @parameter expression="${project.build.directory}"
* @required
*/
private File outputDirectory = null;
/**
* Name of the generated archive.
*
* @parameter expression="${project.build.finalName}"
* @required
*/
private String finalName = null;
/**
* Location of resources directory for additional content to include in the KAR.
* Note that it includes everything under classes so as to include maven-remote-resources
*
* @parameter expression="${project.build.directory}/classes"
*/
private File resourcesDir;
/**
* The features file to use as instructions
*
* @parameter default-value="${project.build.directory}/feature/feature.xml"
*/
private File featuresFile;
/**
* The internal repository in the kar.
*
* @parameter default-value="${repositoryPath}"
*/
private String repositoryPath = "repository/";
public void execute() throws MojoExecutionException, MojoFailureException {
List<Artifact> resources = readResources();
// build the archive
File archive = createArchive(resources);
// attach the generated archive to install/deploy
Artifact artifact = factory.createArtifact(project.getGroupId(), project.getArtifactId(), project.getVersion(), null, "kar");
artifact.setFile(archive);
project.addAttachedArtifact(artifact);
}
/**
* Read and load the bundles and configuration files contained in the features file.
*
* @return a list of resources artifact.
* @throws MojoExecutionException
*/
private List<Artifact> readResources() throws MojoExecutionException {
List<Artifact> resources = new ArrayList<Artifact>();
try {
RepositoryImpl featuresRepo = new RepositoryImpl(featuresFile.toURI());
Feature[] features = featuresRepo.getFeatures();
for (Feature feature : features) {
for (BundleInfo bundle : feature.getBundles()) {
if (!bundle.isDependency()) {
resources.add(resourceToArtifact(bundle.getLocation(), false));
}
}
for (ConfigFileInfo configFile : feature.getConfigurationFiles()) {
resources.add(resourceToArtifact(configFile.getLocation(), false));
}
}
return resources;
} catch (MojoExecutionException e) {
throw e;
} catch (Exception e) {
throw new MojoExecutionException("Could not interpret features XML file", e);
}
}
private File createArchive(List<Artifact> bundles) throws MojoExecutionException {
ArtifactRepositoryLayout layout = new DefaultRepositoryLayout();
File archiveFile = getArchiveFile(outputDirectory, finalName, null);
MavenArchiver archiver = new MavenArchiver();
MavenArchiveConfiguration configuration = new MavenArchiveConfiguration();
archiver.setArchiver(jarArchiver);
archiver.setOutputFile(archiveFile);
try {
// include the features XML file
Artifact featureArtifact = factory.createArtifactWithClassifier(project.getGroupId(), project.getArtifactId(), project.getVersion(), "xml", KarArtifactInstaller.FEATURES_CLASSIFIER);
jarArchiver.addFile(featuresFile, repositoryPath + layout.pathOf(featureArtifact));
for (Artifact artifact : bundles) {
resolver.resolve(artifact, remoteRepos, localRepo);
File localFile = artifact.getFile();
// TODO this may not be reasonable, but... resolved snapshot artifacts have timestamped versions
// which do not work in startup.properties
artifact.setVersion(artifact.getBaseVersion());
String targetFileName = repositoryPath + layout.pathOf(artifact);
jarArchiver.addFile(localFile, targetFileName);
}
if (resourcesDir.isDirectory()) {
archiver.getArchiver().addDirectory(resourcesDir);
}
archiver.createArchive(project, configuration);
return archiveFile;
} catch (Exception e) {
throw new MojoExecutionException("Failed to create kar archive", e);
}
}
protected static File getArchiveFile(final File basedir, final String finalName, String classifier) {
if (classifier == null) {
classifier = "";
} else if (classifier.trim().length() > 0 && !classifier.startsWith("-")) {
classifier = "-" + classifier;
}
return new File(basedir, finalName + classifier + ".kar");
}
}