use of org.apache.karaf.features.internal.model.Feature in project karaf by apache.
the class GenerateDescriptorMojo method writeFeatures.
/*
* Write all project dependencies as feature
*/
private void writeFeatures(PrintStream out) throws ArtifactResolutionException, ArtifactNotFoundException, IOException, JAXBException, SAXException, ParserConfigurationException, XMLStreamException, MojoExecutionException {
getLog().info("Generating feature descriptor file " + outputFile.getAbsolutePath());
//read in an existing feature.xml
ObjectFactory objectFactory = new ObjectFactory();
Features features;
if (inputFile.exists()) {
filter(inputFile, filteredInputFile);
features = readFeaturesFile(filteredInputFile);
} else {
features = objectFactory.createFeaturesRoot();
}
if (features.getName() == null) {
features.setName(project.getArtifactId());
}
Feature feature = null;
for (Feature test : features.getFeature()) {
if (test.getName().equals(primaryFeatureName)) {
feature = test;
}
}
if (feature == null) {
feature = objectFactory.createFeature();
feature.setName(primaryFeatureName);
}
if (!feature.hasVersion()) {
feature.setVersion(project.getArtifact().getBaseVersion());
}
if (feature.getDescription() == null) {
feature.setDescription(project.getName());
}
if (installMode != null) {
feature.setInstall(installMode);
}
if (project.getDescription() != null && feature.getDetails() == null) {
feature.setDetails(project.getDescription());
}
if (includeProjectArtifact) {
Bundle bundle = objectFactory.createBundle();
bundle.setLocation(this.dependencyHelper.artifactToMvn(project.getArtifact(), project.getVersion()));
if (startLevel != null) {
bundle.setStartLevel(startLevel);
}
feature.getBundle().add(bundle);
}
boolean needWrap = false;
// First pass to look for features
// Track other features we depend on and their repositories (we track repositories instead of building them from
// the feature's Maven artifact to allow for multi-feature repositories)
// TODO Initialise the repositories from the existing feature file if any
Map<Dependency, Feature> otherFeatures = new HashMap<>();
Map<Feature, String> featureRepositories = new HashMap<>();
for (final LocalDependency entry : localDependencies) {
Object artifact = entry.getArtifact();
if (excludedArtifactIds.contains(this.dependencyHelper.getArtifactId(artifact))) {
continue;
}
processFeatureArtifact(features, feature, otherFeatures, featureRepositories, artifact, entry.getParent(), true);
}
// Second pass to look for bundles
if (addBundlesToPrimaryFeature) {
localDependency: for (final LocalDependency entry : localDependencies) {
Object artifact = entry.getArtifact();
if (excludedArtifactIds.contains(this.dependencyHelper.getArtifactId(artifact))) {
continue;
}
if (!this.dependencyHelper.isArtifactAFeature(artifact)) {
String bundleName = this.dependencyHelper.artifactToMvn(artifact, getVersionOrRange(entry.getParent(), artifact));
File bundleFile = this.dependencyHelper.resolve(artifact, getLog());
Manifest manifest = getManifest(bundleFile);
for (ConfigFile cf : feature.getConfigfile()) {
if (bundleName.equals(cf.getLocation().replace('\n', ' ').trim())) {
// The bundle matches a configfile, ignore it
continue localDependency;
}
}
if (manifest == null || !ManifestUtils.isBundle(getManifest(bundleFile))) {
bundleName = "wrap:" + bundleName;
needWrap = true;
}
Bundle bundle = null;
for (Bundle b : feature.getBundle()) {
if (bundleName.equals(b.getLocation())) {
bundle = b;
break;
}
}
if (bundle == null) {
bundle = objectFactory.createBundle();
bundle.setLocation(bundleName);
// Check the features this feature depends on don't already contain the dependency
// TODO Perhaps only for transitive dependencies?
boolean includedTransitively = simplifyBundleDependencies && isBundleIncludedTransitively(feature, otherFeatures, bundle);
if (!includedTransitively && (!"provided".equals(entry.getScope()) || !ignoreScopeProvided)) {
feature.getBundle().add(bundle);
}
}
if ("runtime".equals(entry.getScope())) {
bundle.setDependency(true);
}
if (startLevel != null && bundle.getStartLevel() == 0) {
bundle.setStartLevel(startLevel);
}
}
}
}
if (needWrap) {
Dependency wrapDependency = new Dependency();
wrapDependency.setName("wrap");
wrapDependency.setDependency(false);
wrapDependency.setPrerequisite(true);
feature.getFeature().add(wrapDependency);
}
if ((!feature.getBundle().isEmpty() || !feature.getFeature().isEmpty()) && !features.getFeature().contains(feature)) {
features.getFeature().add(feature);
}
// Add any missing repositories for the included features
for (Feature includedFeature : features.getFeature()) {
for (Dependency dependency : includedFeature.getFeature()) {
Feature dependedFeature = otherFeatures.get(dependency);
if (dependedFeature != null && !features.getFeature().contains(dependedFeature)) {
String repository = featureRepositories.get(dependedFeature);
if (repository != null && !features.getRepository().contains(repository)) {
features.getRepository().add(repository);
}
}
}
}
JaxbUtil.marshal(features, out);
try {
checkChanges(features, objectFactory);
} catch (Exception e) {
throw new MojoExecutionException("Features contents have changed", e);
}
getLog().info("...done!");
}
use of org.apache.karaf.features.internal.model.Feature in project karaf by apache.
the class GenerateDescriptorMojo method processFeatureArtifact.
private void processFeatureArtifact(Features features, Feature feature, Map<Dependency, Feature> otherFeatures, Map<Feature, String> featureRepositories, Object artifact, Object parent, boolean add) throws MojoExecutionException, XMLStreamException, JAXBException, IOException {
if (this.dependencyHelper.isArtifactAFeature(artifact) && FEATURE_CLASSIFIER.equals(this.dependencyHelper.getClassifier(artifact))) {
File featuresFile = this.dependencyHelper.resolve(artifact, getLog());
if (featuresFile == null || !featuresFile.exists()) {
throw new MojoExecutionException("Cannot locate file for feature: " + artifact + " at " + featuresFile);
}
Features includedFeatures = readFeaturesFile(featuresFile);
for (String repository : includedFeatures.getRepository()) {
processFeatureArtifact(features, feature, otherFeatures, featureRepositories, new DefaultArtifact(MavenUtil.mvnToAether(repository)), parent, false);
}
for (Feature includedFeature : includedFeatures.getFeature()) {
Dependency dependency = new Dependency(includedFeature.getName(), includedFeature.getVersion());
dependency.setPrerequisite(prerequisiteFeatures.contains(dependency.getName()));
dependency.setDependency(dependencyFeatures.contains(dependency.getName()));
// Determine what dependency we're actually going to use
Dependency matchingDependency = findMatchingDependency(feature.getFeature(), dependency);
if (matchingDependency != null) {
// The feature already has a matching dependency, merge
mergeDependencies(matchingDependency, dependency);
dependency = matchingDependency;
}
// We mustn't de-duplicate here, we may have seen a feature in !add mode
otherFeatures.put(dependency, includedFeature);
if (add) {
if (!feature.getFeature().contains(dependency)) {
feature.getFeature().add(dependency);
}
if (aggregateFeatures) {
features.getFeature().add(includedFeature);
}
}
if (!featureRepositories.containsKey(includedFeature)) {
featureRepositories.put(includedFeature, this.dependencyHelper.artifactToMvn(artifact, getVersionOrRange(parent, artifact)));
}
}
}
}
use of org.apache.karaf.features.internal.model.Feature in project karaf by apache.
the class VerifyMojo method doExecute.
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);
}
}
Set<String> allDescriptors = new LinkedHashSet<>();
if (descriptors == null) {
if (framework == null) {
framework = Collections.singleton("framework");
}
descriptors = new LinkedHashSet<>();
if (framework.contains("framework")) {
allDescriptors.add("mvn:org.apache.karaf.features/framework/" + getVersion("org.apache.karaf.features:framework") + "/xml/features");
}
allDescriptors.add("file:" + project.getBuild().getDirectory() + "/feature/feature.xml");
} else {
allDescriptors.addAll(descriptors);
if (framework != null && framework.contains("framework")) {
allDescriptors.add("mvn:org.apache.karaf.features/framework/" + getVersion("org.apache.karaf.features:framework") + "/xml/features");
}
}
// 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, allDescriptors);
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()) {
Pattern pattern = getPattern(features);
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(new CustomDownloadManager(resolver, executor), 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));
}
}
use of org.apache.karaf.features.internal.model.Feature in project karaf by apache.
the class AbstractFeatureMojo method addFeaturesDependencies.
protected void addFeaturesDependencies(List<Dependency> featureNames, Set<Feature> features, Map<String, Feature> featuresMap, boolean transitive) {
for (Dependency dependency : featureNames) {
Feature f = getMatchingFeature(featuresMap, dependency.getName(), dependency.getVersion());
features.add(f);
if (transitive) {
addFeaturesDependencies(f.getFeature(), features, featuresMap, true);
}
}
}
use of org.apache.karaf.features.internal.model.Feature in project karaf by apache.
the class AbstractFeatureMojo method getMatchingFeature.
private Feature getMatchingFeature(Map<String, Feature> featuresMap, String feature, String version) {
Feature f = null;
if (version != null && !version.equals(Feature.DEFAULT_VERSION)) {
// looking for a specific feature with name and version
f = featuresMap.get(feature + "/" + version);
if (f == null) {
//it's probably is a version range so try to use VersionRange Utils
VersionRange versionRange = new VersionRange(version);
for (String key : featuresMap.keySet()) {
String[] nameVersion = key.split("/");
if (feature.equals(nameVersion[0])) {
String verStr = featuresMap.get(key).getVersion();
Version ver = VersionTable.getVersion(verStr);
if (versionRange.contains(ver)) {
if (f == null || VersionTable.getVersion(f.getVersion()).compareTo(VersionTable.getVersion(featuresMap.get(key).getVersion())) < 0) {
f = featuresMap.get(key);
}
}
}
}
}
} 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;
}
Aggregations