Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.jar.JarInputStream;
import java.util.jar.Manifest;

Expand All @@ -37,6 +39,7 @@
import javax.xml.stream.XMLStreamException;

import org.apache.karaf.features.internal.model.*;
import org.apache.karaf.tooling.utils.Dependency31Helper;
import org.apache.karaf.tooling.utils.DependencyHelper;
import org.apache.karaf.tooling.utils.DependencyHelperFactory;
import org.apache.karaf.tooling.utils.LocalDependency;
Expand Down Expand Up @@ -490,6 +493,7 @@ private void writeFeatures(PrintStream out) throws ArtifactResolutionException,
// TODO Initialise the repositories from the existing feature file if any
Map<Dependency, Feature> otherFeatures = new HashMap<>();
Map<Feature, String> featureRepositories = new HashMap<>();
Set<Object> recognizedFeatures = new HashSet<>();
FeaturesCache cache = new FeaturesCache(featuresCacheSize, artifactCacheSize);
for (final LocalDependency entry : localDependencies) {
Object artifact = entry.getArtifact();
Expand All @@ -499,7 +503,7 @@ private void writeFeatures(PrintStream out) throws ArtifactResolutionException,
}

processFeatureArtifact(features, feature, otherFeatures, featureRepositories, cache, artifact,
entry.getParent(), true);
entry.getParent(), true, recognizedFeatures);
}
// Do not retain cache beyond this point
cache = null;
Expand All @@ -514,7 +518,7 @@ private void writeFeatures(PrintStream out) throws ArtifactResolutionException,
continue;
}

if (!this.dependencyHelper.isArtifactAFeature(artifact)) {
if (!this.dependencyHelper.isArtifactAFeature(artifact) && !recognizedFeatures.contains(artifact)) {
String bundleName = this.dependencyHelper.artifactToMvn(artifact, getVersionOrRange(entry.getParent(), artifact));

for (ConfigFile cf : feature.getConfigfile()) {
Expand Down Expand Up @@ -609,19 +613,33 @@ private void writeFeatures(PrintStream out) throws ArtifactResolutionException,

private void processFeatureArtifact(Features features, Feature feature, Map<Dependency, Feature> otherFeatures,
Map<Feature, String> featureRepositories, FeaturesCache cache,
Object artifact, Object parent, boolean add)
Object artifact, Object parent, boolean add, Set<Object> recognizedFeatures)
throws MojoExecutionException, XMLStreamException, JAXBException, IOException {
if (this.dependencyHelper.isArtifactAFeature(artifact) && FEATURE_CLASSIFIER.equals(
this.dependencyHelper.getClassifier(artifact))) {
File featuresFile = this.dependencyHelper.resolve(artifact, getLog());
boolean isFeature = this.dependencyHelper.isArtifactAFeature(artifact);
File featuresFile = null;
if (!isFeature) {
// For XML artifacts with non-standard classifiers, resolve and check content
featuresFile = this.dependencyHelper.resolve(artifact, getLog());
if (featuresFile != null && featuresFile.exists()
&& Dependency31Helper.isFeaturesXml(featuresFile)) {
isFeature = true;
}
}
if (isFeature) {
if (recognizedFeatures != null) {
recognizedFeatures.add(artifact);
}
if (featuresFile == null) {
featuresFile = this.dependencyHelper.resolve(artifact, getLog());
}
if (featuresFile == null || !featuresFile.exists()) {
throw new MojoExecutionException(
"Cannot locate file for feature: " + artifact + " at " + featuresFile);
}
Features includedFeatures = cache.getFeature(featuresFile);
for (String repository : includedFeatures.getRepository()) {
processFeatureArtifact(features, feature, otherFeatures, featureRepositories, cache,
cache.getArtifact(repository), parent, false);
cache.getArtifact(repository), parent, false, recognizedFeatures);
}
for (Feature includedFeature : includedFeatures.getFeature()) {
Dependency dependency = new Dependency(includedFeature.getName(), includedFeature.getVersion());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,16 @@
import org.codehaus.plexus.util.StringUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;

import static java.lang.String.*;
import static org.apache.commons.lang3.reflect.MethodUtils.invokeMethod;
import static org.apache.karaf.deployer.kar.KarArtifactInstaller.FEATURE_CLASSIFIER;
Expand Down Expand Up @@ -284,7 +290,31 @@ public static boolean isFeature(DependencyNode dependencyNode) {
}

public static boolean isFeature(Artifact artifact) {
return artifact.getExtension().equals("kar") || FEATURE_CLASSIFIER.equals(artifact.getClassifier());
if (artifact.getExtension().equals("kar") || FEATURE_CLASSIFIER.equals(artifact.getClassifier())) {
return true;
}
// For XML artifacts with non-standard classifiers, check actual content when the file is available
if ("xml".equals(artifact.getExtension()) && artifact.getFile() != null && artifact.getFile().exists()) {
return isFeaturesXml(artifact.getFile());
}
return false;
}

public static boolean isFeaturesXml(File file) {
try (InputStream is = new FileInputStream(file)) {
XMLInputFactory xif = XMLInputFactory.newFactory();
xif.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, true);
xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
xif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
XMLStreamReader r = xif.createXMLStreamReader(is);
r.nextTag();
QName name = r.getName();
return name.getLocalPart().equals("features")
&& (name.getNamespaceURI().isEmpty()
|| name.getNamespaceURI().startsWith("http://karaf.apache.org/xmlns/features/"));
} catch (Exception e) {
return false;
}
}

@Override
Expand Down
Loading