You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by cs...@apache.org on 2013/09/30 10:05:37 UTC
svn commit: r1527477 - in
/karaf/trunk/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features:
AbstractFeatureMojo.java AddToRepositoryMojo.java
ExportFeatureMetaDataMojo.java
Author: cschneider
Date: Mon Sep 30 08:05:37 2013
New Revision: 1527477
URL: http://svn.apache.org/r1527477
Log:
KARAF-2491 Create extra karaf maven plugin command for meta data export and optionally eliminate duplicates
Added:
karaf/trunk/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/AbstractFeatureMojo.java (with props)
karaf/trunk/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/ExportFeatureMetaDataMojo.java (with props)
Modified:
karaf/trunk/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/AddToRepositoryMojo.java
Added: karaf/trunk/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/AbstractFeatureMojo.java
URL: http://svn.apache.org/viewvc/karaf/trunk/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/AbstractFeatureMojo.java?rev=1527477&view=auto
==============================================================================
--- karaf/trunk/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/AbstractFeatureMojo.java (added)
+++ karaf/trunk/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/AbstractFeatureMojo.java Mon Sep 30 08:05:37 2013
@@ -0,0 +1,271 @@
+/**
+ *
+ * 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.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.karaf.tooling.features.model.BundleRef;
+import org.apache.karaf.tooling.features.model.Feature;
+import org.apache.karaf.tooling.features.model.Repository;
+import org.apache.karaf.tooling.utils.MojoSupport;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.AbstractArtifactResolutionException;
+import org.apache.maven.plugin.MojoExecutionException;
+
+/**
+ * Common functionality for mojos that need to reolve features
+ */
+public abstract class AbstractFeatureMojo extends MojoSupport {
+
+ protected static final String KARAF_CORE_STANDARD_FEATURE_URL = "mvn:org.apache.karaf.features/standard/%s/xml/features";
+ protected static final String KARAF_CORE_ENTERPRISE_FEATURE_URL = "mvn:org.apache.karaf.features/enterprise/%s/xml/features";
+ /**
+ * @parameter
+ */
+ protected List<String> descriptors;
+
+ protected Set<Artifact> descriptorArtifacts;
+
+ /**
+ * @parameter
+ */
+ protected List<String> features;
+
+ /**
+ * the target karaf version used to resolve Karaf core features descriptors
+ *
+ * @parameter
+ */
+ protected String karafVersion;
+ /**
+ * @parameter
+ */
+ protected boolean addTransitiveFeatures = true;
+ /**
+ * @parameter
+ */
+ private boolean includeMvnBasedDescriptors = false;
+ /**
+ * @parameter
+ */
+ private boolean failOnArtifactResolutionError = true;
+ /**
+ * @parameter
+ */
+ private boolean resolveDefinedRepositoriesRecursively = true;
+
+ /**
+ * @parameter
+ */
+ protected boolean skipNonMavenProtocols = true;
+
+ /**
+ * The start level exported when no explicit start level is set for a bundle
+ * @parameter
+ */
+ private int defaultStartLevel = 80;
+
+ /**
+ * Internal counter for garbage collection
+ */
+ private int resolveCount = 0;
+
+ public AbstractFeatureMojo() {
+ super();
+ descriptorArtifacts = new HashSet<Artifact>();
+ }
+
+ protected void addFeatureRepo(String featureUrl) throws MojoExecutionException {
+ Artifact featureDescArtifact = resourceToArtifact(featureUrl, true);
+ if (featureDescArtifact == null) {
+ return;
+ }
+ try {
+ resolveArtifact(featureDescArtifact, remoteRepos);
+ descriptors.add(0, featureUrl);
+ } catch (Exception e) {
+ getLog().warn("Can't add " + featureUrl + " in the descriptors set");
+ getLog().debug(e);
+ }
+ }
+
+ protected void retrieveDescriptorsRecursively(String uri, Set<String> bundles, Map<String, Feature> featuresMap) {
+ // let's ensure a mvn: based url is sitting in the local repo before we try reading it
+ Artifact descriptor;
+ try {
+ descriptor = resourceToArtifact(uri, true);
+ } catch (MojoExecutionException e) {
+ throw new RuntimeException(e.getMessage(), e);
+ }
+ if (descriptor != null) {
+ resolveArtifact(descriptor, remoteRepos);
+ descriptorArtifacts.add(descriptor);
+ }
+ if (includeMvnBasedDescriptors) {
+ bundles.add(uri);
+ }
+ URI repoURI = URI.create(translateFromMaven(uri.replaceAll(" ", "%20")));
+ Repository repo = new Repository(repoURI, defaultStartLevel);
+ for (Feature f : repo.getFeatures()) {
+ featuresMap.put(f.getName() + "/" + f.getVersion(), f);
+ }
+ if (resolveDefinedRepositoriesRecursively) {
+ for (String r : repo.getDefinedRepositories()) {
+ retrieveDescriptorsRecursively(r, bundles, featuresMap);
+ }
+ }
+ }
+
+ /**
+ * Resolves and copies the given artifact to the repository path.
+ * Prefers to resolve using the repository of the artifact if present.
+ *
+ * @param artifact
+ * @param remoteRepos
+ */
+ @SuppressWarnings("deprecation")
+ protected void resolveArtifact(Artifact artifact, List<ArtifactRepository> remoteRepos) {
+ try {
+ List<ArtifactRepository> usedRemoteRepos = artifact.getRepository() != null ?
+ Collections.singletonList(artifact.getRepository())
+ : remoteRepos;
+ resolver.resolve(artifact, usedRemoteRepos, localRepo);
+ } catch (AbstractArtifactResolutionException e) {
+ if (failOnArtifactResolutionError) {
+ throw new RuntimeException("Can't resolve bundle " + artifact, e);
+ }
+ getLog().error("Can't resolve bundle " + artifact, e);
+ }
+ }
+
+
+ /**
+ * Populate the features by traversing the listed features and their
+ * dependencies if transitive is true
+ *
+ * @param featureNames
+ * @param features
+ * @param featuresMap
+ * @param transitive
+ */
+ protected void addFeatures(List<String> featureNames, Set<Feature> features, Map<String, Feature> featuresMap, boolean transitive) {
+ for (String feature : featureNames) {
+ Feature f = getMatchingFeature(featuresMap, feature);
+ features.add(f);
+ if (transitive) {
+ addFeatures(f.getDependencies(), features, featuresMap, true);
+ }
+ }
+ }
+
+ private Feature getMatchingFeature(Map<String, Feature> featuresMap, String feature) {
+ // feature could be only the name or name/version
+ int delimIndex = feature.indexOf('/');
+ String version = null;
+ if (delimIndex > 0) {
+ version = feature.substring(delimIndex + 1);
+ feature = feature.substring(0, delimIndex);
+ }
+ Feature f = null;
+ if (version != null) {
+ // looking for a specific feature with name and version
+ f = featuresMap.get(feature + "/" + version);
+ } else {
+ // looking for the first feature name (whatever the version is)
+ for (String key : featuresMap.keySet()) {
+ String[] nameVersion = key.split("/");
+ if (feature.equals(nameVersion[0])) {
+ f = featuresMap.get(key);
+ break;
+ }
+ }
+ }
+ if (f == null) {
+ throw new IllegalArgumentException("Unable to find the feature '" + feature + "'");
+ }
+ return f;
+ }
+
+ protected Set<Feature> resolveFeatures() throws MojoExecutionException {
+ Set<Feature> featuresSet = new HashSet<Feature>();
+ if (karafVersion == null) {
+ Package p = Package.getPackage("org.apache.karaf.tooling.features");
+ karafVersion = p.getImplementationVersion();
+ }
+
+ addFeatureRepo(String.format(KARAF_CORE_ENTERPRISE_FEATURE_URL, karafVersion));
+ addFeatureRepo(String.format(KARAF_CORE_STANDARD_FEATURE_URL, karafVersion));
+ addFeatureRepo(String.format(KARAF_CORE_STANDARD_FEATURE_URL, karafVersion));
+
+ try {
+ Set<String> artifactsToCopy = new HashSet<String>();
+ Map<String, Feature> featuresMap = new HashMap<String, Feature>();
+ for (String uri : descriptors) {
+ retrieveDescriptorsRecursively(uri, artifactsToCopy, featuresMap);
+ }
+
+ // no features specified, handle all of them
+ if (features == null) {
+ features = new ArrayList<String>(featuresMap.keySet());
+ }
+
+ addFeatures(features, featuresSet, featuresMap, addTransitiveFeatures);
+
+ getLog().info("Base repo: " + localRepo.getUrl());
+ for (Feature feature : featuresSet) {
+ resolveBundles(feature.getBundles());
+ }
+ } catch (Exception e) {
+ throw new MojoExecutionException("Error populating repository", e);
+ }
+ return featuresSet;
+ }
+
+ private void resolveBundles(List<BundleRef> bundleRefs) throws MojoExecutionException {
+ for (BundleRef bundle : bundleRefs) {
+ Artifact artifact = resourceToArtifact(bundle.getUrl(), skipNonMavenProtocols);
+ if (artifact != null) {
+ // Store artifact in bundle for later export
+ bundle.setArtifact(artifact);
+ resolveArtifact(artifact, remoteRepos);
+ }
+ checkDoGarbageCollect();
+ }
+ }
+
+ /**
+ * Maven ArtifactResolver leaves file handles around so need to clean up
+ * or we will run out of file descriptors
+ */
+ protected void checkDoGarbageCollect() {
+ if (this.resolveCount++ % 100 == 0) {
+ System.gc();
+ System.runFinalization();
+ }
+ }
+
+
+}
\ No newline at end of file
Propchange: karaf/trunk/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/AbstractFeatureMojo.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: karaf/trunk/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/AddToRepositoryMojo.java
URL: http://svn.apache.org/viewvc/karaf/trunk/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/AddToRepositoryMojo.java?rev=1527477&r1=1527476&r2=1527477&view=diff
==============================================================================
--- karaf/trunk/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/AddToRepositoryMojo.java (original)
+++ karaf/trunk/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/AddToRepositoryMojo.java Mon Sep 30 08:05:37 2013
@@ -18,23 +18,12 @@
package org.apache.karaf.tooling.features;
import java.io.File;
-import java.io.FileOutputStream;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import org.apache.karaf.tooling.features.model.BundleRef;
import org.apache.karaf.tooling.features.model.Feature;
-import org.apache.karaf.tooling.features.model.Repository;
-import org.apache.karaf.tooling.utils.MojoSupport;
import org.apache.maven.artifact.Artifact;
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.artifact.resolver.AbstractArtifactResolutionException;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
@@ -48,257 +37,54 @@ import org.apache.maven.plugin.MojoFailu
* @inheritByDefault true
* @description Add the features to the repository
*/
-public class AddToRepositoryMojo extends MojoSupport {
-
- private final static String KARAF_CORE_STANDARD_FEATURE_URL =
- "mvn:org.apache.karaf.features/standard/%s/xml/features";
- private final static String KARAF_CORE_ENTERPRISE_FEATURE_URL =
- "mvn:org.apache.karaf.features/enterprise/%s/xml/features";
-
- /**
- * @parameter
- */
- private List<String> descriptors;
-
- /**
- * @parameter
- */
- private List<String> features;
+public class AddToRepositoryMojo extends AbstractFeatureMojo {
/**
* @parameter expression="${project.build.directory}/features-repo"
*/
- private File repository;
-
- /**
- * the target karaf version used to resolve Karaf core features descriptors
- *
- * @parameter
- */
- private String karafVersion;
+ protected File repository;
/**
- * @parameter
- */
- private boolean includeMvnBasedDescriptors = false;
-
- /**
- * @parameter
- */
- private List<CopyFileBasedDescriptor> copyFileBasedDescriptors;
-
- /**
- * @parameter
- */
- private boolean skipNonMavenProtocols = true;
-
- /**
- * @parameter
- */
- private boolean failOnArtifactResolutionError = true;
-
- /**
- * @parameter
- */
- private boolean resolveDefinedRepositoriesRecursively = true;
-
- /**
- * @parameter
- */
- private boolean addTransitiveFeatures = true;
-
- /**
* If set to true the exported bundles will be directly copied into the repository dir.
* If set to false the default maven repository layout will be used
* @parameter
*/
private boolean flatRepoLayout;
-
+
/**
- * If set to true then the resolved features and bundles will be exported into a single xml file.
- * This is intended to allow further build scripts to create configs for OSGi containers
* @parameter
*/
- private boolean exportMetaData;
-
- /**
- * Name of the file for exported feature meta data
- *
- * @parameter expression="${project.build.directory}/features.xml"
- */
- private File metaDataFile;
-
- /**
- * The start level exported when no explicit start level is set for a bundle
- * @parameter
- */
- private int defaultStartLevel = 80;
-
- /**
- * Internal counter for garbage collection
- */
- private int resolveCount = 0;
+ protected List<CopyFileBasedDescriptor> copyFileBasedDescriptors;
public void execute() throws MojoExecutionException, MojoFailureException {
- if (karafVersion == null) {
- Package p = Package.getPackage("org.apache.karaf.tooling.features");
- karafVersion = p.getImplementationVersion();
+ Set<Feature> featuresSet = resolveFeatures();
+
+ for (Artifact descriptor : descriptorArtifacts) {
+ copy(descriptor, repository);
}
- addFeatureRepo(String.format(KARAF_CORE_ENTERPRISE_FEATURE_URL, karafVersion));
- addFeatureRepo(String.format(KARAF_CORE_STANDARD_FEATURE_URL, karafVersion));
- addFeatureRepo(String.format(KARAF_CORE_STANDARD_FEATURE_URL, karafVersion));
-
- try {
- Set<String> artifactsToCopy = new HashSet<String>();
- Map<String, Feature> featuresMap = new HashMap<String, Feature>();
- for (String uri : descriptors) {
- retrieveDescriptorsRecursively(uri, artifactsToCopy, featuresMap);
- }
-
- // no features specified, handle all of them
- if (features == null) {
- features = new ArrayList<String>(featuresMap.keySet());
- }
-
- Set<Feature> featuresSet = new HashSet<Feature>();
-
- addFeatures(features, featuresSet, featuresMap, addTransitiveFeatures);
-
- getLog().info("Base repo: " + localRepo.getUrl());
- for (Feature feature : featuresSet) {
- copyBundlesToDestRepository(feature.getBundles());
- copyArtifactsToDestRepository(feature.getConfigFiles());
- }
-
- copyFileBasedDescriptorsToDestRepository();
-
- if (exportMetaData) {
- exportMetaData(featuresSet, metaDataFile);
- }
- } catch (Exception e) {
- throw new MojoExecutionException("Error populating repository", e);
- }
- }
-
- private void exportMetaData(Set<Feature> featuresSet, File metaDataFile) {
- try {
- FeatureMetaDataExporter exporter = new FeatureMetaDataExporter(new FileOutputStream(metaDataFile));
- for (Feature feature : featuresSet) {
- exporter.writeFeature(feature);
- }
- exporter.close();
- } catch (Exception e) {
- throw new RuntimeException("Error writing feature meta data to " + metaDataFile + ": " + e.getMessage(), e);
- }
- }
-
- private void addFeatureRepo(String featureUrl) throws MojoExecutionException {
- Artifact featureDescArtifact = resourceToArtifact(featureUrl, true);
- if (featureDescArtifact == null) {
- return;
- }
- try {
- resolveAndCopyArtifact(featureDescArtifact, remoteRepos);
- descriptors.add(0, featureUrl);
- } catch (Exception e) {
- getLog().warn("Can't add " + featureUrl + " in the descriptors set");
- getLog().debug(e);
- }
- }
-
- private void retrieveDescriptorsRecursively(String uri, Set<String> bundles, Map<String, Feature> featuresMap) {
- // let's ensure a mvn: based url is sitting in the local repo before we try reading it
- Artifact descriptor;
- try {
- descriptor = resourceToArtifact(uri, true);
- } catch (MojoExecutionException e) {
- throw new RuntimeException(e.getMessage(), e);
- }
- if (descriptor != null) {
- resolveAndCopyArtifact(descriptor, remoteRepos);
- }
- if (includeMvnBasedDescriptors) {
- bundles.add(uri);
- }
- URI repoURI = URI.create(translateFromMaven(uri.replaceAll(" ", "%20")));
- Repository repo = new Repository(repoURI, defaultStartLevel);
- for (Feature f : repo.getFeatures()) {
- featuresMap.put(f.getName() + "/" + f.getVersion(), f);
- }
- if (resolveDefinedRepositoriesRecursively) {
- for (String r : repo.getDefinedRepositories()) {
- retrieveDescriptorsRecursively(r, bundles, featuresMap);
- }
- }
+ for (Feature feature : featuresSet) {
+ copyBundlesToDestRepository(feature.getBundles());
+ copyArtifactsToDestRepository(feature.getConfigFiles());
+ }
+
+ copyFileBasedDescriptorsToDestRepository();
+
}
private void copyBundlesToDestRepository(List<BundleRef> bundleRefs) throws MojoExecutionException {
for (BundleRef bundle : bundleRefs) {
- Artifact artifact = resourceToArtifact(bundle.getUrl(), skipNonMavenProtocols);
- if (artifact != null) {
- // Store artifact in bundle for later export
- bundle.setArtifact(artifact);
- resolveAndCopyArtifact(artifact, remoteRepos);
- }
- checkDoGarbageCollect();
- }
- }
-
- private void copyArtifactsToDestRepository(List<String> list) throws MojoExecutionException {
- for (String bundle : list) {
- Artifact artifact = resourceToArtifact(bundle, skipNonMavenProtocols);
+ Artifact artifact = bundle.getArtifact();
if (artifact != null) {
- resolveAndCopyArtifact(artifact, remoteRepos);
- }
- checkDoGarbageCollect();
- }
- }
-
- /**
- * Maven ArtifactResolver leaves file handles around so need to clean up
- * or we will run out of file descriptors
- */
- private void checkDoGarbageCollect() {
- if (this.resolveCount++ % 100 == 0) {
- System.gc();
- System.runFinalization();
- }
- }
-
- private void copyFileBasedDescriptorsToDestRepository() {
- if (copyFileBasedDescriptors != null) {
- for (CopyFileBasedDescriptor fileBasedDescriptor : copyFileBasedDescriptors) {
- File destDir = new File(repository, fileBasedDescriptor.getTargetDirectory());
- File destFile = new File(destDir, fileBasedDescriptor.getTargetFileName());
- copy(fileBasedDescriptor.getSourceFile(), destFile);
+ copy(artifact, repository);
}
}
}
- /**
- * Resolves and copies the given artifact to the repository path.
- * Prefers to resolve using the repository of the artifact if present.
- *
- * @param artifact
- * @param remoteRepos
- */
- @SuppressWarnings("deprecation")
- private void resolveAndCopyArtifact(Artifact artifact, List<ArtifactRepository> remoteRepos) {
- try {
- getLog().info("Copying artifact: " + artifact);
- List<ArtifactRepository> usedRemoteRepos = artifact.getRepository() != null ?
- Collections.singletonList(artifact.getRepository())
- : remoteRepos;
- resolver.resolve(artifact, usedRemoteRepos, localRepo);
- File destFile = new File(repository, getRelativePath(artifact));
- copy(artifact.getFile(), destFile);
- } catch (AbstractArtifactResolutionException e) {
- if (failOnArtifactResolutionError) {
- throw new RuntimeException("Can't resolve bundle " + artifact, e);
- }
- getLog().error("Can't resolve bundle " + artifact, e);
- }
+ protected void copy(Artifact artifact, File destRepository) {
+ getLog().info("Copying artifact: " + artifact);
+ File destFile = new File(destRepository, getRelativePath(artifact));
+ copy(artifact.getFile(), destFile);
}
/**
@@ -308,61 +94,30 @@ public class AddToRepositoryMojo extends
* @return relative path of the given artifact in a default repo layout
*/
private String getRelativePath(Artifact artifact) {
- String dir = (this.flatRepoLayout) ? "" : MavenUtil.getDir(artifact);
+ String dir = (this.flatRepoLayout) ? "" : MavenUtil.getDir(artifact);
String name = MavenUtil.getFileName(artifact);
return dir + name;
}
-
-
-
-
- /**
- * Populate the features by traversing the listed features and their
- * dependencies if transitive is true
- *
- * @param featureNames
- * @param features
- * @param featuresMap
- * @param transitive
- */
- private void addFeatures(List<String> featureNames, Set<Feature> features,
- Map<String, Feature> featuresMap, boolean transitive) {
- for (String feature : featureNames) {
- Feature f = getMatchingFeature(featuresMap, feature);
- features.add(f);
- if (transitive) {
- addFeatures(f.getDependencies(), features, featuresMap, true);
+ private void copyArtifactsToDestRepository(List<String> list) throws MojoExecutionException {
+ for (String bundle : list) {
+ Artifact artifact = resourceToArtifact(bundle, skipNonMavenProtocols);
+ if (artifact != null) {
+ resolveArtifact(artifact, remoteRepos);
+ copy(artifact, repository);
}
+ checkDoGarbageCollect();
}
}
-
- private Feature getMatchingFeature(Map<String, Feature> featuresMap, String feature) {
- // feature could be only the name or name/version
- int delimIndex = feature.indexOf('/');
- String version = null;
- if (delimIndex > 0) {
- version = feature.substring(delimIndex + 1);
- feature = feature.substring(0, delimIndex);
- }
- Feature f = null;
- if (version != null) {
- // looking for a specific feature with name and version
- f = featuresMap.get(feature + "/" + version);
- } else {
- // looking for the first feature name (whatever the version is)
- for (String key : featuresMap.keySet()) {
- String[] nameVersion = key.split("/");
- if (feature.equals(nameVersion[0])) {
- f = featuresMap.get(key);
- break;
- }
+
+ private void copyFileBasedDescriptorsToDestRepository() {
+ if (copyFileBasedDescriptors != null) {
+ for (CopyFileBasedDescriptor fileBasedDescriptor : copyFileBasedDescriptors) {
+ File destDir = new File(repository, fileBasedDescriptor.getTargetDirectory());
+ File destFile = new File(destDir, fileBasedDescriptor.getTargetFileName());
+ copy(fileBasedDescriptor.getSourceFile(), destFile);
}
}
- if (f == null) {
- throw new IllegalArgumentException("Unable to find the feature '" + feature + "'");
- }
- return f;
}
}
Added: karaf/trunk/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/ExportFeatureMetaDataMojo.java
URL: http://svn.apache.org/viewvc/karaf/trunk/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/ExportFeatureMetaDataMojo.java?rev=1527477&view=auto
==============================================================================
--- karaf/trunk/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/ExportFeatureMetaDataMojo.java (added)
+++ karaf/trunk/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/ExportFeatureMetaDataMojo.java Mon Sep 30 08:05:37 2013
@@ -0,0 +1,125 @@
+/**
+ *
+ * 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.io.FileOutputStream;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.karaf.tooling.features.model.BundleRef;
+import org.apache.karaf.tooling.features.model.Feature;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.osgi.framework.Version;
+
+/**
+ * Export meta data about features
+ *
+ * @goal features-export-meta-data
+ * @phase compile
+ * @execute phase="compile"
+ * @requiresDependencyResolution runtime
+ * @inheritByDefault true
+ * @description Export meta data about features
+ */
+public class ExportFeatureMetaDataMojo extends AbstractFeatureMojo {
+
+ /**
+ * If set to true then all bundles will be merged into one combined feature.
+ * In this case duplicates will be eliminated
+ *
+ * @parameter
+ */
+ private boolean mergedFeature;
+
+ /**
+ * If set to true then for each bundle symbolic name only the highest version will be used
+ * @parameter
+ */
+ protected boolean oneVersion;
+
+ /**
+ * Name of the file for exported feature meta data
+ *
+ * @parameter expression="${project.build.directory}/features.xml"
+ */
+ private File metaDataFile;
+
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ Set<Feature> featuresSet = resolveFeatures();
+ if (mergedFeature) {
+ Feature feature = oneVersion ? mergeFeatureOneVersion(featuresSet) : mergeFeature(featuresSet);
+ featuresSet = new HashSet<Feature>();
+ featuresSet.add(feature);
+ }
+ try {
+ metaDataFile.getParentFile().mkdirs();
+ FeatureMetaDataExporter exporter = new FeatureMetaDataExporter(new FileOutputStream(metaDataFile));
+ for (Feature feature : featuresSet) {
+ exporter.writeFeature(feature);
+ }
+ exporter.close();
+ } catch (Exception e) {
+ throw new RuntimeException("Error writing feature meta data to " + metaDataFile + ": " + e.getMessage(), e);
+ }
+ }
+
+ private Feature mergeFeature(Set<Feature> featuresSet) {
+ Feature merged = new Feature("merged");
+ Set<String> bundleIds = new HashSet<String>();
+ for (Feature feature : featuresSet) {
+ for (BundleRef bundle : feature.getBundles()) {
+ bundle.readManifest();
+ String bundleId = bundle.getBundleSymbolicName() + ":" + bundle.getBundleVersion();
+ if (!bundleIds.contains(bundleId)) {
+ bundleIds.add(bundleId);
+ merged.getBundles().add(bundle);
+ }
+ }
+ }
+ return merged;
+ }
+
+ private Feature mergeFeatureOneVersion(Set<Feature> featuresSet) {
+ Feature merged = new Feature("merged");
+ Map<String, BundleRef> bundleVersions = new HashMap<String, BundleRef>();
+ for (Feature feature : featuresSet) {
+ for (BundleRef bundle : feature.getBundles()) {
+ bundle.readManifest();
+ BundleRef existingBundle = bundleVersions.get(bundle.getBundleSymbolicName());
+ if (existingBundle != null) {
+ Version existingVersion = new Version(existingBundle.getBundleVersion());
+ Version newVersion = new Version(bundle.getBundleVersion());
+ if (newVersion.compareTo(existingVersion) > 0) {
+ bundleVersions.put(bundle.getBundleSymbolicName(), bundle);
+ }
+ } else {
+ bundleVersions.put(bundle.getBundleSymbolicName(), bundle);
+ }
+ }
+ }
+ for (BundleRef bundle : bundleVersions.values()) {
+ merged.getBundles().add(bundle);
+ }
+ return merged;
+ }
+
+}
Propchange: karaf/trunk/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/features/ExportFeatureMetaDataMojo.java
------------------------------------------------------------------------------
svn:mime-type = text/plain