You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2015/04/17 11:34:56 UTC
[4/5] karaf git commit: [KARAF-3671] Clean up karaf-maven-plugin goals
http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/VerifyMojo.java
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/VerifyMojo.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/VerifyMojo.java
new file mode 100644
index 0000000..db8a9c5
--- /dev/null
+++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/VerifyMojo.java
@@ -0,0 +1,805 @@
+/*
+ * 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;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+import java.util.regex.Pattern;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import aQute.bnd.osgi.Macro;
+import aQute.bnd.osgi.Processor;
+import org.apache.felix.resolver.Logger;
+import org.apache.felix.resolver.ResolverImpl;
+import org.apache.felix.utils.version.VersionRange;
+import org.apache.felix.utils.version.VersionTable;
+import org.apache.karaf.features.FeatureEvent;
+import org.apache.karaf.features.FeaturesService;
+import org.apache.karaf.features.internal.download.DownloadCallback;
+import org.apache.karaf.features.internal.download.DownloadManager;
+import org.apache.karaf.features.internal.download.Downloader;
+import org.apache.karaf.features.internal.download.StreamProvider;
+import org.apache.karaf.features.internal.model.Conditional;
+import org.apache.karaf.features.internal.model.ConfigFile;
+import org.apache.karaf.features.internal.model.Feature;
+import org.apache.karaf.features.internal.model.Features;
+import org.apache.karaf.features.internal.model.JaxbUtil;
+import org.apache.karaf.features.internal.resolver.ResourceBuilder;
+import org.apache.karaf.features.internal.resolver.ResourceImpl;
+import org.apache.karaf.features.internal.resolver.ResourceUtils;
+import org.apache.karaf.features.internal.service.Deployer;
+import org.apache.karaf.features.internal.service.State;
+import org.apache.karaf.features.internal.util.MapUtils;
+import org.apache.karaf.features.internal.util.MultiException;
+import org.apache.karaf.profile.assembly.CustomDownloadManager;
+import org.apache.karaf.tooling.utils.MojoSupport;
+import org.apache.karaf.util.config.PropertiesLoader;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+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.MavenProject;
+import org.ops4j.pax.url.mvn.MavenResolver;
+import org.ops4j.pax.url.mvn.MavenResolvers;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.Version;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.framework.startlevel.BundleStartLevel;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+import org.osgi.resource.Wire;
+import org.osgi.service.resolver.ResolutionException;
+
+import static java.util.jar.JarFile.MANIFEST_NAME;
+
+@Mojo(name = "verify", requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME)
+public class VerifyMojo extends MojoSupport {
+
+ @Parameter(property = "descriptors")
+ protected Set<String> descriptors;
+
+ @Parameter(property = "features")
+ protected Set<String> features;
+
+ @Parameter(property = "framework")
+ protected Set<String> framework;
+
+ @Parameter(property = "configuration")
+ protected String configuration;
+
+ @Parameter(property = "distribution", defaultValue = "org.apache.karaf:apache-karaf")
+ protected String distribution;
+
+ @Parameter(property = "javase")
+ protected String javase;
+
+ @Parameter(property = "dist-dir")
+ protected String distDir;
+
+ @Parameter(property = "additional-metadata")
+ protected File additionalMetadata;
+
+ @Parameter(property = "ignore-missing-conditions")
+ protected boolean ignoreMissingConditions;
+
+ @Parameter(property = "fail")
+ protected String fail = "end";
+
+ @Parameter(property = "verify-transitive")
+ protected boolean verifyTransitive = false;
+
+ @Parameter(defaultValue = "${project}", readonly = true)
+ protected MavenProject project;
+
+ protected MavenResolver resolver;
+
+ @Override
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ Hashtable<String, String> config = new Hashtable<>();
+ StringBuilder remote = new StringBuilder();
+ for (Object obj : project.getRemoteProjectRepositories()) {
+ if (remote.length() > 0) {
+ remote.append(",");
+ }
+ remote.append(invoke(obj, "getUrl"));
+ remote.append("@id=").append(invoke(obj, "getId"));
+ if (!((Boolean) invoke(getPolicy(obj, false), "isEnabled"))) {
+ remote.append("@noreleases");
+ }
+ if ((Boolean) invoke(getPolicy(obj, true), "isEnabled")) {
+ remote.append("@snapshots");
+ }
+ }
+ getLog().info("Using repositories: " + remote.toString());
+ config.put("maven.repositories", remote.toString());
+ // TODO: add more configuration bits ?
+ resolver = MavenResolvers.createMavenResolver(config, "maven");
+ doExecute();
+ }
+
+ private Object invoke(Object object, String getter) throws MojoExecutionException {
+ try {
+ return object.getClass().getMethod(getter).invoke(object);
+ } catch (Exception e) {
+ throw new MojoExecutionException("Unable to build remote repository from " + object.toString(), e);
+ }
+ }
+
+ private Object getPolicy(Object object, boolean snapshots) throws MojoExecutionException {
+ return invoke(object, "getPolicy", new Class[] { Boolean.TYPE }, new Object[] { snapshots });
+ }
+
+ private Object invoke(Object object, String getter, Class[] types, Object[] params) throws MojoExecutionException {
+ try {
+ return object.getClass().getMethod(getter, types).invoke(object, params);
+ } catch (Exception e) {
+ throw new MojoExecutionException("Unable to build remote repository from " + object.toString(), e);
+ }
+ }
+
+ protected void doExecute() throws MojoExecutionException, MojoFailureException {
+ System.setProperty("karaf.home", "target/karaf");
+ System.setProperty("karaf.data", "target/karaf/data");
+
+ Hashtable<String, String> properties = new Hashtable<>();
+
+ if (additionalMetadata != null) {
+ try (Reader reader = new FileReader(additionalMetadata)) {
+ Properties metadata = new Properties();
+ metadata.load(reader);
+ for (Enumeration<?> e = metadata.propertyNames(); e.hasMoreElements(); ) {
+ Object key = e.nextElement();
+ Object val = metadata.get(key);
+ properties.put(key.toString(), val.toString());
+ }
+ } catch (IOException e) {
+ throw new MojoExecutionException("Unable to load additional metadata from " + additionalMetadata, e);
+ }
+ }
+
+ // TODO: allow using external configuration ?
+ ScheduledExecutorService executor = Executors.newScheduledThreadPool(8);
+ DownloadManager manager = new CustomDownloadManager(resolver, executor);
+ final Map<String, Features> repositories;
+ Map<String, List<Feature>> allFeatures = new HashMap<>();
+ try {
+ repositories = loadRepositories(manager, descriptors);
+ for (String repoUri : repositories.keySet()) {
+ List<Feature> features = repositories.get(repoUri).getFeature();
+ // Ack features to inline configuration files urls
+ for (Feature feature : features) {
+ for (org.apache.karaf.features.internal.model.Bundle bi : feature.getBundle()) {
+ String loc = bi.getLocation();
+ String nloc = null;
+ if (loc.contains("file:")) {
+ for (ConfigFile cfi : feature.getConfigfile()) {
+ if (cfi.getFinalname().substring(1)
+ .equals(loc.substring(loc.indexOf("file:") + "file:".length()))) {
+ nloc = cfi.getLocation();
+ }
+ }
+ }
+ if (nloc != null) {
+ Field field = bi.getClass().getDeclaredField("location");
+ field.setAccessible(true);
+ field.set(bi, loc.substring(0, loc.indexOf("file:")) + nloc);
+ }
+ }
+ }
+ allFeatures.put(repoUri, features);
+ }
+ } catch (Exception e) {
+ throw new MojoExecutionException("Unable to load features descriptors", e);
+ }
+
+ List<Feature> featuresToTest = new ArrayList<>();
+ if (verifyTransitive) {
+ for (List<Feature> features : allFeatures.values()) {
+ featuresToTest.addAll(features);
+ }
+ } else {
+ for (String uri : descriptors) {
+ featuresToTest.addAll(allFeatures.get(uri));
+ }
+ }
+ if (features != null && !features.isEmpty()) {
+ StringBuilder sb = new StringBuilder();
+ for (String feature : features) {
+ if (sb.length() > 0) {
+ sb.append("|");
+ }
+ String p = feature.replaceAll("\\.", "\\\\.").replaceAll("\\*", ".*");
+ sb.append(p);
+ if (!feature.contains("/")) {
+ sb.append("/.*");
+ }
+ }
+ Pattern pattern = Pattern.compile(sb.toString());
+ for (Iterator<Feature> iterator = featuresToTest.iterator(); iterator.hasNext();) {
+ Feature feature = iterator.next();
+ String id = feature.getName() + "/" + feature.getVersion();
+ if (!pattern.matcher(id).matches()) {
+ iterator.remove();
+ }
+ }
+ }
+
+ for (String fmk : framework) {
+ properties.put("feature.framework." + fmk, fmk);
+ }
+ List<Exception> failures = new ArrayList<>();
+ for (Feature feature : featuresToTest) {
+ try {
+ String id = feature.getName() + "/" + feature.getVersion();
+ verifyResolution(manager, repositories, Collections.singleton(id), properties);
+ getLog().info("Verification of feature " + id + " succeeded");
+ } catch (Exception e) {
+ if (e.getCause() instanceof ResolutionException) {
+ getLog().warn(e.getMessage());
+ } else {
+ getLog().warn(e);
+ }
+ failures.add(e);
+ if ("first".equals(fail)) {
+ throw e;
+ }
+ }
+ for (Conditional cond : feature.getConditional()) {
+ Set<String> ids = new LinkedHashSet<>();
+ ids.add(feature.getId());
+ ids.addAll(cond.getCondition());
+ try {
+ verifyResolution(manager, repositories, ids, properties);
+ getLog().info("Verification of feature " + ids + " succeeded");
+ } catch (Exception e) {
+ if (ignoreMissingConditions && e.getCause() instanceof ResolutionException) {
+ boolean ignore = true;
+ Collection<Requirement> requirements = ((ResolutionException) e.getCause()).getUnresolvedRequirements();
+ for (Requirement req : requirements) {
+ ignore &= (IdentityNamespace.IDENTITY_NAMESPACE.equals(req.getNamespace())
+ && ResourceUtils.TYPE_FEATURE.equals(req.getAttributes().get("type"))
+ && cond.getCondition().contains(req.getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE).toString()));
+ }
+ if (ignore) {
+ getLog().warn("Feature resolution failed for " + ids
+ + "\nMessage: " + e.getCause().getMessage());
+ continue;
+ }
+ }
+ if (e.getCause() instanceof ResolutionException) {
+ getLog().warn(e.getMessage());
+ } else {
+ getLog().warn(e);
+ }
+ failures.add(e);
+ if ("first".equals(fail)) {
+ throw e;
+ }
+ }
+ }
+ }
+ if ("end".equals(fail) && !failures.isEmpty()) {
+ throw new MojoExecutionException("Verification failures", new MultiException("Verification failures", failures));
+ }
+ }
+
+ private void verifyResolution(DownloadManager manager, final Map<String, Features> repositories, Set<String> features, Hashtable<String, String> properties) throws MojoExecutionException {
+ try {
+ Bundle systemBundle = getSystemBundle(getMetadata(properties, "metadata#"));
+ DummyDeployCallback callback = new DummyDeployCallback(systemBundle, repositories.values());
+ Deployer deployer = new Deployer(manager, new ResolverImpl(new MavenResolverLog()), callback);
+
+
+ // Install framework
+ Deployer.DeploymentRequest request = createDeploymentRequest();
+
+ for (String fmwk : framework) {
+ MapUtils.addToMapSet(request.requirements, FeaturesService.ROOT_REGION, fmwk);
+ }
+ try {
+ deployer.deploy(callback.getDeploymentState(), request);
+ } catch (Exception e) {
+ throw new MojoExecutionException("Unable to resolve framework features", e);
+ }
+
+
+ /*
+ boolean resolveOptionalImports = getResolveOptionalImports(properties);
+
+ DeploymentBuilder builder = new DeploymentBuilder(
+ manager,
+ null,
+ repositories.values(),
+ -1 // Disable url handlers
+ );
+ Map<String, Resource> downloadedResources = builder.download(
+ getPrefixedProperties(properties, "feature."),
+ getPrefixedProperties(properties, "bundle."),
+ getPrefixedProperties(properties, "fab."),
+ getPrefixedProperties(properties, "req."),
+ getPrefixedProperties(properties, "override."),
+ getPrefixedProperties(properties, "optional."),
+ getMetadata(properties, "metadata#")
+ );
+
+ for (String uri : getPrefixedProperties(properties, "resources.")) {
+ builder.addResourceRepository(new MetadataRepository(new HttpMetadataProvider(uri)));
+ }
+ */
+
+
+ // Install features
+ for (String feature : features) {
+ MapUtils.addToMapSet(request.requirements, FeaturesService.ROOT_REGION, feature);
+ }
+ try {
+ Set<String> prereqs = new HashSet<>();
+ while (true) {
+ try {
+ deployer.deploy(callback.getDeploymentState(), request);
+ break;
+ } catch (Deployer.PartialDeploymentException e) {
+ if (!prereqs.containsAll(e.getMissing())) {
+ prereqs.addAll(e.getMissing());
+ } else {
+ throw new Exception("Deployment aborted due to loop in missing prerequisites: " + e.getMissing());
+ }
+ }
+ }
+ // TODO: find unused resources ?
+ } catch (Exception e) {
+ throw new MojoExecutionException("Feature resolution failed for " + features
+ + "\nMessage: " + e.getMessage()
+ + "\nRepositories: " + toString(new TreeSet<>(repositories.keySet()))
+ + "\nResources: " + toString(new TreeSet<>(manager.getProviders().keySet())), e);
+ }
+
+
+ } catch (MojoExecutionException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new MojoExecutionException("Error verifying feature " + features + "\nMessage: " + e.getMessage(), e);
+ }
+ }
+
+ private Deployer.DeploymentRequest createDeploymentRequest() {
+ Deployer.DeploymentRequest request = new Deployer.DeploymentRequest();
+ request.bundleUpdateRange = FeaturesService.DEFAULT_BUNDLE_UPDATE_RANGE;
+ request.featureResolutionRange = FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE;
+ request.overrides = new HashSet<>();
+ request.requirements = new HashMap<>();
+ request.stateChanges = new HashMap<>();
+ request.options = EnumSet.noneOf(FeaturesService.Option.class);
+ return request;
+ }
+
+ private String toString(Collection<String> collection) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("{\n");
+ for (String s : collection) {
+ sb.append("\t").append(s).append("\n");
+ }
+ sb.append("}");
+ return sb.toString();
+ }
+
+ private Bundle getSystemBundle(Map<String, Map<VersionRange, Map<String, String>>> metadata) throws Exception {
+ URL configPropURL;
+ if (configuration != null) {
+ configPropURL = new URL(configuration);
+ } else {
+ Artifact karafDistro = project.getArtifactMap().get(distribution);
+ if (karafDistro == null) {
+ throw new MojoFailureException("The karaf distribution " + distribution + " is not a dependency");
+ }
+ if ("kar".equals(karafDistro.getType()) && distDir == null) {
+ distDir = "resources";
+ }
+ String dir = distDir;
+ if (dir == null) {
+ dir = karafDistro.getArtifactId() + "-" + karafDistro.getBaseVersion();
+ }
+ configPropURL = new URL("jar:file:" + karafDistro.getFile() + "!/" + dir + "/etc/config.properties");
+ }
+ org.apache.felix.utils.properties.Properties configProps = PropertiesLoader.loadPropertiesFile(configPropURL, true);
+// copySystemProperties(configProps);
+ if (javase == null) {
+ configProps.put("java.specification.version", System.getProperty("java.specification.version"));
+ } else {
+ configProps.put("java.specification.version", javase);
+ }
+ configProps.substitute();
+
+ Attributes attributes = new Attributes();
+ attributes.putValue(Constants.BUNDLE_MANIFESTVERSION, "2");
+ attributes.putValue(Constants.BUNDLE_SYMBOLICNAME, "system.bundle");
+ attributes.putValue(Constants.BUNDLE_VERSION, "0.0.0");
+
+ String exportPackages = configProps.getProperty("org.osgi.framework.system.packages");
+ if (configProps.containsKey("org.osgi.framework.system.packages.extra")) {
+ exportPackages += "," + configProps.getProperty("org.osgi.framework.system.packages.extra");
+ }
+ exportPackages = exportPackages.replaceAll(",\\s*,", ",");
+ attributes.putValue(Constants.EXPORT_PACKAGE, exportPackages);
+
+ String systemCaps = configProps.getProperty("org.osgi.framework.system.capabilities");
+ attributes.putValue(Constants.PROVIDE_CAPABILITY, systemCaps);
+
+ // TODO: support metadata overrides on system bundle
+// attributes = DeploymentBuilder.overrideAttributes(attributes, metadata);
+
+ final Hashtable<String, String> headers = new Hashtable<>();
+ for (Map.Entry attr : attributes.entrySet()) {
+ headers.put(attr.getKey().toString(), attr.getValue().toString());
+ }
+
+ final FakeBundleRevision resource = new FakeBundleRevision(headers, "system-bundle", 0l);
+ return resource.getBundle();
+ }
+
+
+ public static Map<String, Features> loadRepositories(DownloadManager manager, Set<String> uris) throws Exception {
+ final Map<String, Features> loaded = new HashMap<>();
+ final Downloader downloader = manager.createDownloader();
+ for (String repository : uris) {
+ downloader.download(repository, new DownloadCallback() {
+ @Override
+ public void downloaded(final StreamProvider provider) throws Exception {
+ try (InputStream is = provider.open()) {
+ Features featuresModel = JaxbUtil.unmarshal(provider.getUrl(), is, false);
+ synchronized (loaded) {
+ loaded.put(provider.getUrl(), featuresModel);
+ for (String innerRepository : featuresModel.getRepository()) {
+ downloader.download(innerRepository, this);
+ }
+ }
+ }
+ }
+ });
+ }
+ downloader.await();
+ return loaded;
+ }
+
+ public static Set<String> getPrefixedProperties(Map<String, String> properties, String prefix) {
+ Set<String> result = new HashSet<>();
+ for (String key : properties.keySet()) {
+ if (key.startsWith(prefix)) {
+ String url = properties.get(key);
+ if (url == null || url.length() == 0) {
+ url = key.substring(prefix.length());
+ }
+ if (!url.isEmpty()) {
+ result.add(url);
+ }
+ }
+ }
+ return result;
+ }
+
+ public static Map<String, Map<VersionRange, Map<String, String>>> getMetadata(Map<String, String> properties, String prefix) {
+ Map<String, Map<VersionRange, Map<String, String>>> result = new HashMap<>();
+ for (String key : properties.keySet()) {
+ if (key.startsWith(prefix)) {
+ String val = properties.get(key);
+ key = key.substring(prefix.length());
+ String[] parts = key.split("#");
+ if (parts.length == 3) {
+ Map<VersionRange, Map<String, String>> ranges = result.get(parts[0]);
+ if (ranges == null) {
+ ranges = new HashMap<>();
+ result.put(parts[0], ranges);
+ }
+ String version = parts[1];
+ if (!version.startsWith("[") && !version.startsWith("(")) {
+ Processor processor = new Processor();
+ processor.setProperty("@", VersionTable.getVersion(version).toString());
+ Macro macro = new Macro(processor);
+ version = macro.process("${range;[==,=+)}");
+ }
+ VersionRange range = new VersionRange(version);
+ Map<String, String> hdrs = ranges.get(range);
+ if (hdrs == null) {
+ hdrs = new HashMap<>();
+ ranges.put(range, hdrs);
+ }
+ hdrs.put(parts[2], val);
+ }
+ }
+ }
+ return result;
+ }
+
+ public static class FakeBundleRevision extends ResourceImpl implements BundleRevision, BundleStartLevel {
+
+ private final Bundle bundle;
+ private int startLevel;
+
+ public FakeBundleRevision(final Hashtable<String, String> headers, final String location, final long bundleId) throws BundleException {
+ ResourceBuilder.build(this, location, headers);
+ this.bundle = (Bundle) Proxy.newProxyInstance(
+ getClass().getClassLoader(),
+ new Class[] { Bundle.class },
+ new InvocationHandler() {
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ if (method.getName().equals("hashCode")) {
+ return FakeBundleRevision.this.hashCode();
+ } else if (method.getName().equals("equals")) {
+ return proxy == args[0];
+ } else if (method.getName().equals("toString")) {
+ return bundle.getSymbolicName() + "/" + bundle.getVersion();
+ } else if (method.getName().equals("adapt")) {
+ if (args.length == 1 && args[0] == BundleRevision.class) {
+ return FakeBundleRevision.this;
+ } else if (args.length == 1 && args[0] == BundleStartLevel.class) {
+ return FakeBundleRevision.this;
+ }
+ } else if (method.getName().equals("getHeaders")) {
+ return headers;
+ } else if (method.getName().equals("getBundleId")) {
+ return bundleId;
+ } else if (method.getName().equals("getLocation")) {
+ return location;
+ } else if (method.getName().equals("getSymbolicName")) {
+ String name = headers.get(Constants.BUNDLE_SYMBOLICNAME);
+ int idx = name.indexOf(';');
+ if (idx > 0) {
+ name = name.substring(0, idx).trim();
+ }
+ return name;
+ } else if (method.getName().equals("getVersion")) {
+ return new Version(headers.get(Constants.BUNDLE_VERSION));
+ } else if (method.getName().equals("getState")) {
+ return Bundle.ACTIVE;
+ } else if (method.getName().equals("getLastModified")) {
+ return 0l;
+ }
+ return null;
+ }
+ });
+ }
+
+ @Override
+ public int getStartLevel() {
+ return startLevel;
+ }
+
+ @Override
+ public void setStartLevel(int startLevel) {
+ this.startLevel = startLevel;
+ }
+
+ @Override
+ public boolean isPersistentlyStarted() {
+ return true;
+ }
+
+ @Override
+ public boolean isActivationPolicyUsed() {
+ return false;
+ }
+
+ @Override
+ public String getSymbolicName() {
+ return bundle.getSymbolicName();
+ }
+
+ @Override
+ public Version getVersion() {
+ return bundle.getVersion();
+ }
+
+ @Override
+ public List<BundleCapability> getDeclaredCapabilities(String namespace) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public List<BundleRequirement> getDeclaredRequirements(String namespace) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public int getTypes() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public BundleWiring getWiring() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Bundle getBundle() {
+ return bundle;
+ }
+ }
+
+ public static class DummyDeployCallback implements Deployer.DeployCallback {
+
+ private final Bundle systemBundle;
+ private final Deployer.DeploymentState dstate;
+ private final AtomicLong nextBundleId = new AtomicLong(0);
+
+ public DummyDeployCallback(Bundle sysBundle, Collection<Features> repositories) throws Exception {
+ systemBundle = sysBundle;
+ dstate = new Deployer.DeploymentState();
+ dstate.bundles = new HashMap<>();
+ dstate.features = new HashMap<>();
+ dstate.bundlesPerRegion = new HashMap<>();
+ dstate.filtersPerRegion = new HashMap<>();
+ dstate.state = new State();
+
+ MapUtils.addToMapSet(dstate.bundlesPerRegion, FeaturesService.ROOT_REGION, 0l);
+ dstate.bundles.put(0l, systemBundle);
+ for (Features repo : repositories) {
+ for (Feature f : repo.getFeature()) {
+ dstate.features.put(f.getId(), f);
+ }
+ }
+ }
+
+ public Deployer.DeploymentState getDeploymentState() {
+ return dstate;
+ }
+
+ @Override
+ public void print(String message, boolean verbose) {
+ }
+
+ @Override
+ public void saveState(State state) {
+ dstate.state.replace(state);
+ }
+
+ @Override
+ public void persistResolveRequest(Deployer.DeploymentRequest request) throws IOException {
+ }
+
+ @Override
+ public void installFeature(org.apache.karaf.features.Feature feature) throws IOException, InvalidSyntaxException {
+ }
+
+ @Override
+ public void callListeners(FeatureEvent featureEvent) {
+ }
+
+ @Override
+ public Bundle installBundle(String region, String uri, InputStream is) throws BundleException {
+ try {
+ Hashtable<String, String> headers = new Hashtable<>();
+ ZipInputStream zis = new ZipInputStream(is);
+ ZipEntry entry;
+ while ((entry = zis.getNextEntry()) != null) {
+ if (MANIFEST_NAME.equals(entry.getName())) {
+ Attributes attributes = new Manifest(zis).getMainAttributes();
+ for (Map.Entry attr : attributes.entrySet()) {
+ headers.put(attr.getKey().toString(), attr.getValue().toString());
+ }
+ }
+ }
+ BundleRevision revision = new FakeBundleRevision(headers, uri, nextBundleId.incrementAndGet());
+ Bundle bundle = revision.getBundle();
+ MapUtils.addToMapSet(dstate.bundlesPerRegion, region, bundle.getBundleId());
+ dstate.bundles.put(bundle.getBundleId(), bundle);
+ return bundle;
+ } catch (IOException e) {
+ throw new BundleException("Unable to install bundle", e);
+ }
+ }
+
+ @Override
+ public void updateBundle(Bundle bundle, String uri, InputStream is) throws BundleException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void uninstall(Bundle bundle) throws BundleException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void startBundle(Bundle bundle) throws BundleException {
+ }
+
+ @Override
+ public void stopBundle(Bundle bundle, int options) throws BundleException {
+ }
+
+ @Override
+ public void setBundleStartLevel(Bundle bundle, int startLevel) {
+ }
+
+ @Override
+ public void refreshPackages(Collection<Bundle> bundles) throws InterruptedException {
+ }
+
+ @Override
+ public void resolveBundles(Set<Bundle> bundles, Map<Resource, List<Wire>> wiring, Map<Resource, Bundle> resToBnd) {
+ }
+
+ @Override
+ public void replaceDigraph(Map<String, Map<String, Map<String, Set<String>>>> policies, Map<String, Set<Long>> bundles) throws BundleException, InvalidSyntaxException {
+ }
+ }
+
+ public class MavenResolverLog extends org.apache.felix.resolver.Logger {
+
+ public MavenResolverLog() {
+ super(Logger.LOG_DEBUG);
+ }
+
+ @Override
+ protected void doLog(int level, String msg, Throwable throwable) {
+ switch (level) {
+ case LOG_DEBUG:
+ getLog().debug(msg, throwable);
+ break;
+ case LOG_INFO:
+ getLog().info(msg, throwable);
+ break;
+ case LOG_WARNING:
+ getLog().warn(msg, throwable);
+ break;
+ case LOG_ERROR:
+ getLog().error(msg, throwable);
+ break;
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/AbstractFeatureMojo.java
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/AbstractFeatureMojo.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/AbstractFeatureMojo.java
index 0173e62..d2af3e6 100644
--- a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/AbstractFeatureMojo.java
+++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/AbstractFeatureMojo.java
@@ -42,7 +42,7 @@ import org.apache.maven.plugins.annotations.Parameter;
import org.osgi.framework.Version;
/**
- * Common functionality for mojos that need to reolve features
+ * Common functionality for mojos that need to resolve features
*/
public abstract class AbstractFeatureMojo extends MojoSupport {
http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/AddToRepositoryMojo.java
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/AddToRepositoryMojo.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/AddToRepositoryMojo.java
index ba5eae0..7290695 100644
--- a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/AddToRepositoryMojo.java
+++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/AddToRepositoryMojo.java
@@ -28,18 +28,15 @@ import org.apache.karaf.tooling.utils.MavenUtil;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
+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;
/**
* Add features to a repository directory
- *
- * @goal features-add-to-repository
- * @phase compile
- * @execute phase="compile"
- * @requiresDependencyResolution runtime
- * @inheritByDefault true
- * @description Add the features to the repository
*/
+@Mojo(name = "features-add-to-repository", defaultPhase = LifecyclePhase.COMPILE, requiresDependencyResolution = ResolutionScope.RUNTIME)
public class AddToRepositoryMojo extends AbstractFeatureMojo {
@Parameter(defaultValue = "${project.build.directory}/features-repo")
http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/CreateKarMojo.java
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/CreateKarMojo.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/CreateKarMojo.java
deleted file mode 100644
index 6bd447a..0000000
--- a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/CreateKarMojo.java
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- * 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 java.io.*;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.karaf.deployer.kar.KarArtifactInstaller;
-import org.apache.karaf.features.BundleInfo;
-import org.apache.karaf.features.ConfigFileInfo;
-import org.apache.karaf.features.internal.model.Feature;
-import org.apache.karaf.features.internal.model.Features;
-import org.apache.karaf.features.internal.model.JaxbUtil;
-import org.apache.karaf.tooling.utils.MavenUtil;
-import org.apache.karaf.tooling.utils.MojoSupport;
-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.artifact.repository.metadata.Metadata;
-import org.apache.maven.artifact.repository.metadata.Snapshot;
-import org.apache.maven.artifact.repository.metadata.SnapshotVersion;
-import org.apache.maven.artifact.repository.metadata.Versioning;
-import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Writer;
-import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
-import org.apache.maven.artifact.resolver.ArtifactResolutionException;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
-import org.apache.maven.plugins.annotations.Component;
-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.codehaus.plexus.archiver.Archiver;
-import org.codehaus.plexus.archiver.jar.JarArchiver;
-
-/**
- * Assemble a kar archive from a features.xml file
- */
-@Mojo(name = "features-create-kar", defaultPhase = LifecyclePhase.PACKAGE, requiresDependencyResolution = ResolutionScope.RUNTIME)
-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 = Archiver.class, hint="jar")
- private JarArchiver jarArchiver = null;
-
- /**
- * Directory containing the generated archive.
- */
- @Parameter(defaultValue = "${project.build.directory}")
- private File outputDirectory = null;
-
- /**
- * Name of the generated archive.
- */
- @Parameter(defaultValue = "${project.build.finalName}")
- private String finalName = null;
-
- /**
- * Ignore the dependency flag on the bundles in the features XML
- */
- @Parameter(defaultValue = "false")
- private boolean ignoreDependencyFlag;
-
- /**
- * Classifier to add to the artifact generated. If given, the artifact will be attached.
- * If it's not given, it will merely be written to the output directory according to the finalName.
- */
- @Parameter
- protected String classifier;
-
- /**
- * 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(defaultValue = "${project.build.directory}/classes")
- private File resourcesDir;
-
-
- /**
- * The features file to use as instructions
- */
- @Parameter(defaultValue = "${project.build.directory}/feature/feature.xml")
- private String featuresFile;
-
-
- /**
- * The wrapper repository in the kar.
- */
- @Parameter(defaultValue = "${repositoryPath}")
- private String repositoryPath = "repository/";
-
- private static final Pattern mvnPattern = Pattern.compile("mvn:([^/ ]+)/([^/ ]+)/([^/ ]*)(/([^/ ]+)(/([^/ ]+))?)?");
-
-
- //
- // Mojo
- //
-
- public void execute() throws MojoExecutionException, MojoFailureException {
- File featuresFileResolved = resolveFile(featuresFile);
- String groupId = project.getGroupId();
- String artifactId = project.getArtifactId();
- String version = project.getVersion();
-
- if (isMavenUrl(featuresFile)) {
- Artifact artifactTemp = resourceToArtifact(featuresFile, false);
- if (artifactTemp.getGroupId() != null)
- groupId = artifactTemp.getGroupId();
- if (artifactTemp.getArtifactHandler() != null)
- artifactId = artifactTemp.getArtifactId();
- if (artifactTemp.getVersion() != null)
- version = artifactTemp.getVersion();
- }
-
- List<Artifact> resources = readResources(featuresFileResolved);
-
- // Build the archive
- File archive = createArchive(resources, featuresFileResolved, groupId, artifactId, version);
-
- // if no classifier is specified and packaging is not kar, display a warning
- // and attach artifact
- if (classifier == null && !this.getProject().getPackaging().equals("kar")) {
- this.getLog().warn("Your project should use the \"kar\" packaging or configure a \"classifier\" for kar attachment");
- projectHelper.attachArtifact(getProject(), "kar", null, archive);
- return;
- }
-
- // Attach the generated archive for install/deploy
- if (classifier != null) {
- projectHelper.attachArtifact(getProject(), "kar", classifier, archive);
- } else {
- getProject().getArtifact().setFile(archive);
- }
- }
-
- private File resolveFile(String file) {
- File fileResolved = null;
-
- if (isMavenUrl(file)) {
- fileResolved = new File(fromMaven(file));
- try {
- Artifact artifactTemp = resourceToArtifact(file, false);
- if (!fileResolved.exists()) {
- try {
- artifactResolver.resolve(artifactTemp, remoteRepos, localRepo);
- fileResolved = artifactTemp.getFile();
- } catch (ArtifactResolutionException e) {
- getLog().error("Artifact was not resolved", e);
- } catch (ArtifactNotFoundException e) {
- getLog().error("Artifact was not found", e);
- }
- }
- } catch (MojoExecutionException e) {
- getLog().error(e);
- }
- } else {
- fileResolved = new File(file);
- }
-
- return fileResolved;
- }
-
- /**
- * Read bundles and configuration files in the features file.
- *
- * @return
- * @throws MojoExecutionException
- */
- private List<Artifact> readResources(File featuresFile) throws MojoExecutionException {
- List<Artifact> resources = new ArrayList<Artifact>();
- try {
- Features features = JaxbUtil.unmarshal(featuresFile.toURI().toASCIIString(), false);
- for (Feature feature : features.getFeature()) {
- for (BundleInfo bundle : feature.getBundles()) {
- if (ignoreDependencyFlag || (!ignoreDependencyFlag && !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", e);
- }
- }
-
- /**
- * Generates the configuration archive.
- *
- * @param bundles
- */
- @SuppressWarnings("deprecation")
- private File createArchive(List<Artifact> bundles, File featuresFile, String groupId, String artifactId, String version) throws MojoExecutionException {
- ArtifactRepositoryLayout layout = new DefaultRepositoryLayout();
- File archiveFile = getArchiveFile(outputDirectory, finalName, classifier);
-
- MavenArchiver archiver = new MavenArchiver();
- archiver.setArchiver(jarArchiver);
- archiver.setOutputFile(archiveFile);
-
- try {
- //TODO should .kar be a bundle?
-// archive.addManifestEntry(Constants.BUNDLE_NAME, project.getName());
-// archive.addManifestEntry(Constants.BUNDLE_VENDOR, project.getOrganization().getName());
-// ArtifactVersion version = project.getArtifact().getSelectedVersion();
-// String versionString = "" + version.getMajorVersion() + "." + version.getMinorVersion() + "." + version.getIncrementalVersion();
-// if (version.getQualifier() != null) {
-// versionString += "." + version.getQualifier();
-// }
-// archive.addManifestEntry(Constants.BUNDLE_VERSION, versionString);
-// archive.addManifestEntry(Constants.BUNDLE_MANIFESTVERSION, "2");
-// archive.addManifestEntry(Constants.BUNDLE_DESCRIPTION, project.getDescription());
-// // NB, no constant for this one
-// archive.addManifestEntry("Bundle-License", ((License) project.getLicenses().get(0)).getUrl());
-// archive.addManifestEntry(Constants.BUNDLE_DOCURL, project.getUrl());
-// //TODO this might need some help
-// archive.addManifestEntry(Constants.BUNDLE_SYMBOLICNAME, project.getArtifactId());
-
- //include the feature.xml
- Artifact featureArtifact = factory.createArtifactWithClassifier(groupId, artifactId, version, "xml", KarArtifactInstaller.FEATURE_CLASSIFIER);
- jarArchiver.addFile(featuresFile, repositoryPath + layout.pathOf(featureArtifact));
-
- if (featureArtifact.isSnapshot()) {
- // the artifact is a snapshot, create the maven-metadata-local.xml
- getLog().debug("Feature artifact is a SNAPSHOT, handling the maven-metadata-local.xml");
- File metadataTarget = new File(featuresFile.getParentFile(), "maven-metadata-local.xml");
- getLog().debug("Looking for " + metadataTarget.getAbsolutePath());
- if (!metadataTarget.exists()) {
- // the maven-metadata-local.xml doesn't exist, create it
- getLog().debug(metadataTarget.getAbsolutePath() + " doesn't exist, create it");
- Metadata metadata = new Metadata();
- metadata.setGroupId(featureArtifact.getGroupId());
- metadata.setArtifactId(featureArtifact.getArtifactId());
- metadata.setVersion(featureArtifact.getVersion());
- metadata.setModelVersion("1.1.0");
-
- Versioning versioning = new Versioning();
- versioning.setLastUpdatedTimestamp(new Date(System.currentTimeMillis()));
- Snapshot snapshot = new Snapshot();
- snapshot.setLocalCopy(true);
- versioning.setSnapshot(snapshot);
- SnapshotVersion snapshotVersion = new SnapshotVersion();
- snapshotVersion.setClassifier(featureArtifact.getClassifier());
- snapshotVersion.setVersion(featureArtifact.getVersion());
- snapshotVersion.setExtension(featureArtifact.getType());
- snapshotVersion.setUpdated(versioning.getLastUpdated());
- versioning.addSnapshotVersion(snapshotVersion);
-
- metadata.setVersioning(versioning);
-
- MetadataXpp3Writer metadataWriter = new MetadataXpp3Writer();
- try {
- Writer writer = new FileWriter(metadataTarget);
- metadataWriter.write(writer, metadata);
- } catch (Exception e) {
- getLog().warn("Could not create maven-metadata-local.xml", e);
- getLog().warn("It means that this SNAPSHOT could be overwritten by an older one present on remote repositories");
- }
- }
- getLog().debug("Adding file " + metadataTarget.getAbsolutePath() + " in the jar path " + repositoryPath + layout.pathOf(featureArtifact).substring(0, layout.pathOf(featureArtifact).lastIndexOf('/')) + "/maven-metadata-local.xml");
- jarArchiver.addFile(metadataTarget, repositoryPath + layout.pathOf(featureArtifact).substring(0, layout.pathOf(featureArtifact).lastIndexOf('/')) + "/maven-metadata-local.xml");
- }
-
- for (Artifact artifact : bundles) {
- artifactResolver.resolve(artifact, remoteRepos, localRepo);
- File localFile = artifact.getFile();
-
- if (artifact.isSnapshot()) {
- // the artifact is a snapshot, create the maven-metadata-local.xml
- File metadataTarget = new File(localFile.getParentFile(), "maven-metadata-local.xml");
- if (!metadataTarget.exists()) {
- // the maven-metadata-local.xml doesn't exist, create it
- try {
- MavenUtil.generateMavenMetadata(artifact, metadataTarget);
- } catch (Exception e) {
- getLog().warn("Could not create maven-metadata-local.xml", e);
- getLog().warn("It means that this SNAPSHOT could be overwritten by an older one present on remote repositories");
- }
- }
- jarArchiver.addFile(metadataTarget, repositoryPath + layout.pathOf(artifact).substring(0, layout.pathOf(artifact).lastIndexOf('/')) + "/maven-metadata-local.xml");
- }
-
- //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, archive);
-
- return archiveFile;
- } catch (Exception e) {
- throw new MojoExecutionException("Failed to create archive", e);
- }
- }
-
- protected static boolean isMavenUrl(String name) {
- Matcher m = mvnPattern.matcher(name);
- return m.matches();
- }
-
- /**
- * Return a path for an artifact:
- * - if the input is already a path (doesn't contain ':'), the same path is returned.
- * - if the input is a Maven URL, the input is converted to a default repository location path, type and classifier
- * are optional.
- *
- * @param name artifact data
- * @return path as supplied or a default Maven repository path
- */
- private static String fromMaven(String name) {
- Matcher m = mvnPattern.matcher(name);
- if (!m.matches()) {
- return name;
- }
-
- StringBuilder b = new StringBuilder();
- b.append(m.group(1));
- for (int i = 0; i < b.length(); i++) {
- if (b.charAt(i) == '.') {
- b.setCharAt(i, '/');
- }
- }
- b.append("/"); // groupId
- String artifactId = m.group(2);
- String version = m.group(3);
- String extension = m.group(5);
- String classifier = m.group(7);
- b.append(artifactId).append("/"); // artifactId
- b.append(version).append("/"); // version
- b.append(artifactId).append("-").append(version);
- if (present(classifier)) {
- b.append("-").append(classifier);
- }
- if (present(classifier)) {
- b.append(".").append(extension);
- } else {
- b.append(".jar");
- }
- return b.toString();
- }
-
- private static boolean present(String part) {
- return part != null && !part.isEmpty();
- }
-
- 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");
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/karaf/blob/056239dc/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/InstallKarsMojo.java
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/InstallKarsMojo.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/InstallKarsMojo.java
deleted file mode 100644
index 47ae0a9..0000000
--- a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/InstallKarsMojo.java
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * 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 java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.karaf.profile.assembly.Builder;
-import org.apache.karaf.tooling.utils.DependencyHelper;
-import org.apache.karaf.tooling.utils.DependencyHelperFactory;
-import org.apache.karaf.tooling.utils.IoUtils;
-import org.apache.karaf.tooling.utils.MojoSupport;
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
-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;
-
-/**
- * Installs kar dependencies into a server-under-construction in target/assembly
- */
-@Mojo(name = "install-kars", defaultPhase = LifecyclePhase.PROCESS_RESOURCES, requiresDependencyResolution = ResolutionScope.RUNTIME)
-public class InstallKarsMojo extends MojoSupport {
-
- /**
- * Base directory used to copy the resources during the build (working directory).
- */
- @Parameter(defaultValue = "${project.build.directory}/assembly")
- protected File workDirectory;
-
- /**
- * Features configuration file (etc/org.apache.karaf.features.cfg).
- */
- @Parameter(defaultValue = "${project.build.directory}/assembly/etc/org.apache.karaf.features.cfg")
- protected File featuresCfgFile;
-
- /**
- * startup.properties file.
- */
- @Parameter(defaultValue = "${project.build.directory}/assembly/etc/startup.properties")
- protected File startupPropertiesFile;
-
- /**
- * Directory used during build to construction the Karaf system repository.
- */
- @Parameter(defaultValue="${project.build.directory}/assembly/system")
- protected File systemDirectory;
-
- /**
- * default start level for bundles in features that don't specify it.
- */
- @Parameter
- protected int defaultStartLevel = 30;
-
- @Parameter
- private List<String> startupRepositories;
- @Parameter
- private List<String> bootRepositories;
- @Parameter
- private List<String> installedRepositories;
-
- /**
- * List of features from runtime-scope features xml and kars to be installed into system and listed in startup.properties.
- */
- @Parameter
- private List<String> startupFeatures;
-
- /**
- * List of features from runtime-scope features xml and kars to be installed into system repo and listed in features service boot features.
- */
- @Parameter
- private List<String> bootFeatures;
-
- /**
- * List of features from runtime-scope features xml and kars to be installed into system repo and not mentioned elsewhere.
- */
- @Parameter
- private List<String> installedFeatures;
-
- @Parameter
- private List<String> blacklistedFeatures;
-
- @Parameter
- private List<String> startupBundles;
- @Parameter
- private List<String> bootBundles;
- @Parameter
- private List<String> installedBundles;
- @Parameter
- private List<String> blacklistedBundles;
-
- @Parameter
- private String profilesUri;
-
- @Parameter
- private List<String> bootProfiles;
-
- @Parameter
- private List<String> startupProfiles;
-
- @Parameter
- private List<String> installedProfiles;
-
- @Parameter
- private List<String> blacklistedProfiles;
-
- @Parameter
- private Builder.BlacklistPolicy blacklistPolicy;
-
- /**
- * Ignore the dependency attribute (dependency="[true|false]") on bundle
- */
- @Parameter(defaultValue = "false")
- protected boolean ignoreDependencyFlag;
-
- /**
- * Additional feature repositories
- */
- @Parameter
- protected List<String> featureRepositories;
-
- @Parameter
- protected List<String> libraries;
-
- /**
- * Use reference: style urls in startup.properties
- */
- @Parameter(defaultValue = "false")
- protected boolean useReferenceUrls;
-
- @Parameter
- protected boolean installAllFeaturesByDefault = true;
-
- @Parameter
- protected Builder.KarafVersion karafVersion = Builder.KarafVersion.v4x;
-
- // an access layer for available Aether implementation
- protected DependencyHelper dependencyHelper;
-
- @Override
- public void execute() throws MojoExecutionException, MojoFailureException {
- this.dependencyHelper = DependencyHelperFactory.createDependencyHelper(this.container, this.project, this.mavenSession, getLog());
- try {
- doExecute();
- }
- catch (MojoExecutionException | MojoFailureException e) {
- throw e;
- }
- catch (Exception e) {
- throw new MojoExecutionException("Unable to build assembly", e);
- }
- }
-
- protected void doExecute() throws Exception {
- startupRepositories = nonNullList(startupRepositories);
- bootRepositories = nonNullList(bootRepositories);
- installedRepositories = nonNullList(installedRepositories);
- startupBundles = nonNullList(startupBundles);
- bootBundles = nonNullList(bootBundles);
- installedBundles = nonNullList(installedBundles);
- blacklistedBundles = nonNullList(blacklistedBundles);
- startupFeatures = nonNullList(startupFeatures);
- bootFeatures = nonNullList(bootFeatures);
- installedFeatures = nonNullList(installedFeatures);
- blacklistedFeatures = nonNullList(blacklistedFeatures);
- startupProfiles = nonNullList(startupProfiles);
- bootProfiles = nonNullList(bootProfiles);
- installedProfiles = nonNullList(installedProfiles);
- blacklistedProfiles = nonNullList(blacklistedProfiles);
-
- if (!startupProfiles.isEmpty() || !bootProfiles.isEmpty() || !installedProfiles.isEmpty()) {
- if (profilesUri == null) {
- throw new IllegalArgumentException("profilesDirectory must be specified");
- }
- }
-
- if (featureRepositories != null && !featureRepositories.isEmpty()) {
- getLog().warn("Use of featureRepositories is deprecated, use startupRepositories, bootRepositories or installedRepositories instead");
- startupRepositories.addAll(featureRepositories);
- bootRepositories.addAll(featureRepositories);
- installedRepositories.addAll(featureRepositories);
- }
-
- Builder builder = Builder.newInstance();
-
- // Set up blacklisted items
- builder.blacklistBundles(blacklistedBundles);
- builder.blacklistFeatures(blacklistedFeatures);
- builder.blacklistProfiles(blacklistedProfiles);
- builder.blacklistPolicy(blacklistPolicy);
-
- // creating system directory
- getLog().info("Creating work directory");
- builder.homeDirectory(workDirectory.toPath());
- IoUtils.deleteRecursive(workDirectory);
- workDirectory.mkdirs();
-
- List<String> startupKars = new ArrayList<>();
- List<String> bootKars = new ArrayList<>();
- List<String> installedKars = new ArrayList<>();
-
- // Loading kars and features repositories
- getLog().info("Loading kar and features repositories dependencies");
- for (Artifact artifact : project.getDependencyArtifacts()) {
- Builder.Stage stage;
- switch (artifact.getScope()) {
- case "compile":
- stage = Builder.Stage.Startup;
- break;
- case "runtime":
- stage = Builder.Stage.Boot;
- break;
- case "provided":
- stage = Builder.Stage.Installed;
- break;
- default:
- continue;
- }
- if ("kar".equals(artifact.getType())) {
- String uri = dependencyHelper.artifactToMvn(artifact);
- switch (stage) {
- case Startup: startupKars.add(uri); break;
- case Boot: bootKars.add(uri); break;
- case Installed: installedKars.add(uri); break;
- }
- } else if ("features".equals(artifact.getClassifier())) {
- String uri = dependencyHelper.artifactToMvn(artifact);
- switch (stage) {
- case Startup: startupRepositories.add(uri); break;
- case Boot: bootRepositories.add(uri); break;
- case Installed: installedRepositories.add(uri); break;
- }
- } else if ("jar".equals(artifact.getType()) || "bundle".equals(artifact.getType())) {
- String uri = dependencyHelper.artifactToMvn(artifact);
- switch (stage) {
- case Startup: startupBundles.add(uri); break;
- case Boot: bootBundles.add(uri); break;
- case Installed: installedBundles.add(uri); break;
- }
- }
- }
-
- builder.karafVersion(karafVersion)
- .useReferenceUrls(useReferenceUrls)
- .defaultAddAll(installAllFeaturesByDefault)
- .ignoreDependencyFlag(ignoreDependencyFlag);
- if (profilesUri != null) {
- builder.profilesUris(profilesUri);
- }
- if (libraries != null) {
- builder.libraries(libraries.toArray(new String[libraries.size()]));
- }
- // Startup
- builder.defaultStage(Builder.Stage.Startup)
- .kars(toArray(startupKars))
- .repositories(startupFeatures.isEmpty() && startupProfiles.isEmpty() && installAllFeaturesByDefault, toArray(startupRepositories))
- .features(toArray(startupFeatures))
- .bundles(toArray(startupBundles))
- .profiles(toArray(startupProfiles));
- // Boot
- builder.defaultStage(Builder.Stage.Boot)
- .kars(toArray(bootKars))
- .repositories(bootFeatures.isEmpty() && bootProfiles.isEmpty() && installAllFeaturesByDefault, toArray(bootRepositories))
- .features(toArray(bootFeatures))
- .bundles(toArray(bootBundles))
- .profiles(toArray(bootProfiles));
- // Installed
- builder.defaultStage(Builder.Stage.Installed)
- .kars(toArray(installedKars))
- .repositories(installedFeatures.isEmpty() && installedProfiles.isEmpty() && installAllFeaturesByDefault, toArray(installedRepositories))
- .features(toArray(installedFeatures))
- .bundles(toArray(installedBundles))
- .profiles(toArray(installedProfiles));
-
- builder.generateAssembly();
- }
-
- private String[] toArray(List<String> strings) {
- return strings.toArray(new String[strings.size()]);
- }
-
- private List<String> nonNullList(List<String> list) {
- return list == null ? new ArrayList<String>() : list;
- }
-
-}