You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gg...@apache.org on 2017/12/09 18:46:56 UTC
[karaf] 13/19: [KARAF-5376] Use etc/versions.properties
(configurable) to resolve placeholders in etc/org.apache.karaf.features.xml
This is an automated email from the ASF dual-hosted git repository.
ggrzybek pushed a commit to branch KARAF-5376-overrides_v2
in repository https://gitbox.apache.org/repos/asf/karaf.git
commit 5b5a0e8ed6dfa43209da6d4586de8caae88f03d1
Author: Grzegorz Grzybek <gr...@gmail.com>
AuthorDate: Wed Dec 6 10:37:43 2017 +0100
[KARAF-5376] Use etc/versions.properties (configurable) to resolve placeholders in etc/org.apache.karaf.features.xml
---
.../resources/etc/org.apache.karaf.features.cfg | 9 ++
features/core/pom.xml | 16 ++
.../model/processing/FeaturesProcessing.java | 2 +-
.../karaf/features/internal/osgi/Activator.java | 2 +
.../service/FeaturesProcessingSerializer.java | 171 ++++++++++++++++++++-
.../internal/service/FeaturesProcessorImpl.java | 27 +++-
.../internal/service/FeaturesServiceConfig.java | 27 +++-
.../features/internal/service/BlacklistTest.java | 2 +-
.../internal/service/FeaturesProcessorTest.java | 32 +++-
.../karaf/features/internal/service/fpi03.xml | 30 ++++
pom.xml | 16 ++
.../org/apache/karaf/profile/assembly/Builder.java | 2 +-
12 files changed, 310 insertions(+), 26 deletions(-)
diff --git a/assemblies/features/base/src/main/filtered-resources/resources/etc/org.apache.karaf.features.cfg b/assemblies/features/base/src/main/filtered-resources/resources/etc/org.apache.karaf.features.cfg
index 57b92b4..c0c6594 100644
--- a/assemblies/features/base/src/main/filtered-resources/resources/etc/org.apache.karaf.features.cfg
+++ b/assemblies/features/base/src/main/filtered-resources/resources/etc/org.apache.karaf.features.cfg
@@ -62,3 +62,12 @@ featuresBootAsynchronous=false
# Store cfg file for config element in feature
#
#configCfgStore=true
+
+#
+# Configuration of features processing mechanism (overrides, blacklisting, modification of features)
+# XML file defines instructions related to features processing
+# versions.properties may declare properties to resolve placeholders in XML file
+# both files are relative to ${karaf.etc}
+#
+#featureProcessing=org.apache.karaf.features.xml
+#featureProcessingVersions=versions.properties
diff --git a/features/core/pom.xml b/features/core/pom.xml
index e5eaa85..a2e9729 100644
--- a/features/core/pom.xml
+++ b/features/core/pom.xml
@@ -88,6 +88,19 @@
</dependency>
<dependency>
+ <groupId>org.ops4j.base</groupId>
+ <artifactId>ops4j-base-util-property</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.ops4j.base</groupId>
+ <artifactId>ops4j-base-util-collections</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.ops4j.pax.swissbox</groupId>
+ <artifactId>pax-swissbox-property</artifactId>
+ </dependency>
+
+ <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<scope>test</scope>
@@ -159,6 +172,9 @@
org.apache.karaf.util.xml,
org.eclipse.equinox.internal.region.*;-split-package:=merge-first,
org.apache.felix.resolver.*,
+ org.ops4j.pax.swissbox.*,
+ org.ops4j.util.*,
+ org.ops4j.lang.*
</Private-Package>
<Embed-Dependency>
org.apache.karaf.util;inline="org/apache/karaf/util/XmlUtils*.class"
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/model/processing/FeaturesProcessing.java b/features/core/src/main/java/org/apache/karaf/features/internal/model/processing/FeaturesProcessing.java
index 3f5050b..537057e 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/model/processing/FeaturesProcessing.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/model/processing/FeaturesProcessing.java
@@ -280,7 +280,7 @@ public class FeaturesProcessing {
return null;
}
Version vfloor = new Version(v.getMajor(), v.getMinor(), 0, null);
- parser.setVersion(new VersionRange(false, vfloor, v, true).toString());
+ parser.setVersion(new VersionRange(false, vfloor, v, v.compareTo(vfloor) > 0).toString());
}
return parser.toMvnURI();
} catch (MalformedURLException e) {
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java b/features/core/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java
index a950f90..5ef8870 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java
@@ -92,6 +92,7 @@ public class Activator extends BaseActivator {
public static final String FEATURES_SERVICE_CONFIG_FILE = "org.apache.karaf.features.cfg";
public static final String FEATURES_SERVICE_PROCESSING_FILE = "org.apache.karaf.features.xml";
+ public static final String FEATURES_SERVICE_PROCESSING_VERSIONS_FILE = "versions.properties";
private static final String STATE_FILE = "state.json";
@@ -238,6 +239,7 @@ public class Activator extends BaseActivator {
getInt("scheduleMaxRun", FeaturesService.DEFAULT_SCHEDULE_MAX_RUN),
getString("blacklisted", new File(karafEtc, "blacklisted.properties").toURI().toString()),
getString("featureProcessing", new File(karafEtc, FEATURES_SERVICE_PROCESSING_FILE).toURI().toString()),
+ getString("featureProcessingVersions", new File(karafEtc, FEATURES_SERVICE_PROCESSING_VERSIONS_FILE).toURI().toString()),
getString("serviceRequirements", FeaturesService.ServiceRequirementsBehavior.Default.getValue()));
}
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesProcessingSerializer.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesProcessingSerializer.java
index 4a72fe3..6fcbbcb 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesProcessingSerializer.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesProcessingSerializer.java
@@ -24,13 +24,15 @@ import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
+import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.UnmarshallerHandler;
+import javax.xml.parsers.SAXParserFactory;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
@@ -42,8 +44,21 @@ import javax.xml.transform.stream.StreamResult;
import org.apache.karaf.features.internal.model.processing.FeaturesProcessing;
import org.apache.karaf.features.internal.model.processing.ObjectFactory;
import org.apache.karaf.util.xml.IndentingXMLEventWriter;
+import org.ops4j.pax.swissbox.property.BundleContextPropertyResolver;
+import org.ops4j.util.property.DictionaryPropertyResolver;
+import org.ops4j.util.property.PropertyResolver;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.AttributesImpl;
/**
* A class to help serialize {@link org.apache.karaf.features.internal.model.processing.FeaturesProcessing} model
@@ -53,12 +68,15 @@ public class FeaturesProcessingSerializer {
public static Logger LOG = LoggerFactory.getLogger(FeaturesProcessingSerializer.class);
+ private final BundleContext bundleContext;
private JAXBContext FEATURES_PROCESSING_CONTEXT;
public FeaturesProcessingSerializer() {
+ Bundle bundle = FrameworkUtil.getBundle(this.getClass());
+ this.bundleContext = bundle == null ? null : bundle.getBundleContext();
try {
FEATURES_PROCESSING_CONTEXT = JAXBContext.newInstance(ObjectFactory.class);
- } catch (JAXBException e) {
+ } catch (Exception e) {
throw new RuntimeException(e);
}
}
@@ -68,9 +86,43 @@ public class FeaturesProcessingSerializer {
* @param stream
* @return
*/
- public FeaturesProcessing read(InputStream stream) throws JAXBException {
+ public FeaturesProcessing read(InputStream stream) throws Exception {
+ return this.read(stream, null);
+ }
+
+ /**
+ * Reads {@link FeaturesProcessing features processing model} from input stream
+ * @param stream
+ * @param versions additional properties to resolve placeholders in features processing XML
+ * @return
+ */
+ public FeaturesProcessing read(InputStream stream, Properties versions) throws Exception {
Unmarshaller unmarshaller = FEATURES_PROCESSING_CONTEXT.createUnmarshaller();
- return (FeaturesProcessing) unmarshaller.unmarshal(stream);
+ UnmarshallerHandler handler = unmarshaller.getUnmarshallerHandler();
+
+ // BundleContextPropertyResolver gives access to e.g., ${karaf.base}
+ final PropertyResolver resolver = bundleContext == null ? new DictionaryPropertyResolver(versions)
+ : new DictionaryPropertyResolver(versions, new BundleContextPropertyResolver(bundleContext));
+
+ // indirect unmarshaling with property resolution inside XML attribute values and CDATA
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ spf.setNamespaceAware(true);
+ XMLReader xmlReader = spf.newSAXParser().getXMLReader();
+ xmlReader.setContentHandler(new ResolvingContentHandler(new Properties() {
+ @Override
+ public String getProperty(String key) {
+ return resolver.get(key);
+ }
+
+ @Override
+ public String getProperty(String key, String defaultValue) {
+ String value = resolver.get(key);
+ return value == null ? defaultValue : value;
+ }
+ }, handler));
+ xmlReader.parse(new InputSource(stream));
+
+ return (FeaturesProcessing) handler.getResult();
}
/**
@@ -156,4 +208,115 @@ public class FeaturesProcessingSerializer {
}
}
+ private static class ResolvingContentHandler implements ContentHandler {
+
+ public static Logger LOG = LoggerFactory.getLogger(ResolvingContentHandler.class);
+
+ private Properties properties;
+ private ContentHandler target;
+
+ private boolean inElement = false;
+ private StringWriter sw = new StringWriter();
+
+ public ResolvingContentHandler(Properties properties, ContentHandler target) {
+ this.properties = properties;
+ this.target = target;
+ }
+
+ @Override
+ public void setDocumentLocator(Locator locator) {
+ target.setDocumentLocator(locator);
+ }
+
+ @Override
+ public void startDocument() throws SAXException {
+ target.startDocument();
+ }
+
+ @Override
+ public void endDocument() throws SAXException {
+ target.endDocument();
+ }
+
+ @Override
+ public void startPrefixMapping(String prefix, String uri) throws SAXException {
+ target.startPrefixMapping(prefix, uri);
+ }
+
+ @Override
+ public void endPrefixMapping(String prefix) throws SAXException {
+ target.endPrefixMapping(prefix);
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
+ AttributesImpl resolvedAttributes = new AttributesImpl(atts);
+ for (int i = 0; i < atts.getLength(); i++) {
+ resolvedAttributes.setAttribute(i, atts.getURI(i), atts.getLocalName(i), atts.getQName(i),
+ atts.getType(i), resolve(atts.getValue(i)));
+ }
+ if (inElement) {
+ flushBuffer(false);
+ }
+ inElement = true;
+ target.startElement(uri, localName, qName, resolvedAttributes);
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+ if (inElement) {
+ flushBuffer(true);
+ inElement = false;
+ }
+ target.endElement(uri, localName, qName);
+ }
+
+ @Override
+ public void characters(char[] ch, int start, int length) throws SAXException {
+ if (inElement) {
+ sw.append(new String(ch, start, length));
+ } else {
+ target.characters(ch, start, length);
+ }
+ }
+
+ @Override
+ public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
+ // only elements without PCDATA in DTD have whitespace passed to this method. so ignore
+ target.ignorableWhitespace(ch, start, length);
+ }
+
+ @Override
+ public void processingInstruction(String target, String data) throws SAXException {
+ this.target.processingInstruction(target, data);
+ }
+
+ @Override
+ public void skippedEntity(String name) throws SAXException {
+ target.skippedEntity(name);
+ }
+
+ /**
+ * Pass collected characters to target {@link ContentHandler}
+ * @param resolve whether to expect placeholders in collected text
+ */
+ private void flushBuffer(boolean resolve) throws SAXException {
+ String value = sw.toString();
+ String resolved = resolve ? resolve(value) : value;
+
+ target.characters(resolved.toCharArray(), 0, resolved.length());
+ sw = new StringWriter();
+ }
+
+ private String resolve(String value) {
+ String resolved = org.ops4j.util.collections.PropertyResolver.resolve(properties, value);
+ if (resolved.contains("${")) {
+ // there are still unresolved properties - just log warning
+ LOG.warn("Value {} has unresolved properties, please check configuration.", value);
+ }
+ return resolved;
+ }
+
+ }
+
}
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesProcessorImpl.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesProcessorImpl.java
index 4e3fa04..87d26e6 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesProcessorImpl.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesProcessorImpl.java
@@ -18,11 +18,13 @@
*/
package org.apache.karaf.features.internal.service;
+import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.List;
+import java.util.Properties;
import java.util.Set;
import org.apache.karaf.features.BundleInfo;
@@ -49,7 +51,7 @@ public class FeaturesProcessorImpl implements FeaturesProcessor {
public static Logger LOG = LoggerFactory.getLogger(FeaturesProcessorImpl.class);
- private static FeaturesProcessingSerializer serializer = new FeaturesProcessingSerializer();
+ private FeaturesProcessingSerializer serializer = new FeaturesProcessingSerializer();
// empty, but fully functional features processing configuration
private FeaturesProcessing processing = new FeaturesProcessing();
@@ -58,14 +60,25 @@ public class FeaturesProcessorImpl implements FeaturesProcessor {
* <p>Creates instance of features processor using 1 external URI, additional {@link Blacklist} instance
* and additional set of override clauses.</p>
* @param featureModificationsURI
+ * @param featureProcessingVersions
* @param blacklistDefinitions
* @param overrides
*/
- public FeaturesProcessorImpl(String featureModificationsURI, Blacklist blacklistDefinitions, Set<String> overrides) {
+ public FeaturesProcessorImpl(String featureModificationsURI, String featureProcessingVersions,
+ Blacklist blacklistDefinitions, Set<String> overrides) {
if (featureModificationsURI != null) {
try {
try (InputStream stream = new URL(featureModificationsURI).openStream()) {
- processing = serializer.read(stream);
+ Properties versions = new Properties();
+ if (featureProcessingVersions != null) {
+ File versionsProperties = new File(new URL(featureProcessingVersions).getPath());
+ if (versionsProperties.isFile()) {
+ try (InputStream propsStream = new URL(featureProcessingVersions).openStream()) {
+ versions.load(propsStream);
+ }
+ }
+ }
+ processing = serializer.read(stream, versions);
}
} catch (FileNotFoundException e) {
LOG.debug("Can't find feature processing file (" + featureModificationsURI + "), skipping");
@@ -80,11 +93,13 @@ public class FeaturesProcessorImpl implements FeaturesProcessor {
/**
* <p>Creates instance of features processor using 3 external (optional) URIs.</p>
* @param featureModificationsURI
+ * @param featureProcessingVersions
* @param blacklistedURI
* @param overridesURI
*/
- public FeaturesProcessorImpl(String featureModificationsURI, String blacklistedURI, String overridesURI) {
- this(featureModificationsURI, new Blacklist(blacklistedURI), Overrides.loadOverrides(overridesURI));
+ public FeaturesProcessorImpl(String featureModificationsURI, String featureProcessingVersions,
+ String blacklistedURI, String overridesURI) {
+ this(featureModificationsURI, featureProcessingVersions, new Blacklist(blacklistedURI), Overrides.loadOverrides(overridesURI));
}
/**
@@ -93,7 +108,7 @@ public class FeaturesProcessorImpl implements FeaturesProcessor {
* @param configuration
*/
public FeaturesProcessorImpl(FeaturesServiceConfig configuration) {
- this(configuration.featureModifications, configuration.blacklisted, configuration.overrides);
+ this(configuration.featureModifications, configuration.featureProcessingVersions, configuration.blacklisted, configuration.overrides);
}
/**
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceConfig.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceConfig.java
index 7fb0f26..5ea4fea 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceConfig.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceConfig.java
@@ -65,25 +65,32 @@ public class FeaturesServiceConfig {
public final String featureModifications;
/**
+ * Location of <code>etc/versions.properties</code> to read properties to resolve placeholders in
+ * {@link #featureModifications}
+ */
+ public final String featureProcessingVersions;
+
+ /**
* Location of <code>etc/overrides.properties</code>
*/
@Deprecated
public final String overrides;
public FeaturesServiceConfig() {
- this(null, null, null);
+ this(null, null, null, null);
}
- public FeaturesServiceConfig(String featureModifications) {
- this(null, FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE, FeaturesService.DEFAULT_BUNDLE_UPDATE_RANGE, null, 1, 0, 0, null, featureModifications, null);
+ public FeaturesServiceConfig(String featureModifications, String featureProcessingVersions) {
+ this(null, FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE, FeaturesService.DEFAULT_BUNDLE_UPDATE_RANGE, null, 1, 0, 0, null, featureModifications, featureProcessingVersions, null);
}
@Deprecated
- public FeaturesServiceConfig(String overrides, String blacklisted, String featureModifications) {
- this(overrides, FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE, FeaturesService.DEFAULT_BUNDLE_UPDATE_RANGE, null, 1, 0, 0, blacklisted, featureModifications, null);
+ public FeaturesServiceConfig(String overrides, String blacklisted, String featureModifications, String featureProcessingVersions) {
+ this(overrides, FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE, FeaturesService.DEFAULT_BUNDLE_UPDATE_RANGE, null, 1, 0, 0, blacklisted, featureModifications, featureProcessingVersions, null);
}
- public FeaturesServiceConfig(String featureResolutionRange, String bundleUpdateRange, String updateSnapshots, int downloadThreads, long scheduleDelay, int scheduleMaxRun, String featureModifications, String serviceRequirements) {
+ public FeaturesServiceConfig(String featureResolutionRange, String bundleUpdateRange, String updateSnapshots, int downloadThreads, long scheduleDelay, int scheduleMaxRun,
+ String featureModifications, String featureProcessingVersions, String serviceRequirements) {
this.overrides = null;
this.featureResolutionRange = featureResolutionRange;
this.bundleUpdateRange = bundleUpdateRange;
@@ -93,11 +100,16 @@ public class FeaturesServiceConfig {
this.scheduleMaxRun = scheduleMaxRun;
this.blacklisted = null;
this.featureModifications = featureModifications;
+ this.featureProcessingVersions = featureProcessingVersions;
this.serviceRequirements = serviceRequirements;
}
@Deprecated
- public FeaturesServiceConfig(String overrides, String featureResolutionRange, String bundleUpdateRange, String updateSnapshots, int downloadThreads, long scheduleDelay, int scheduleMaxRun, String blacklisted, String featureModifications, String serviceRequirements) {
+ public FeaturesServiceConfig(String overrides, String featureResolutionRange, String bundleUpdateRange,
+ String updateSnapshots, int downloadThreads, long scheduleDelay, int scheduleMaxRun,
+ String blacklisted,
+ String featureModifications, String featureProcessingVersions,
+ String serviceRequirements) {
this.overrides = overrides;
this.featureResolutionRange = featureResolutionRange;
this.bundleUpdateRange = bundleUpdateRange;
@@ -107,6 +119,7 @@ public class FeaturesServiceConfig {
this.scheduleMaxRun = scheduleMaxRun;
this.blacklisted = blacklisted;
this.featureModifications = featureModifications;
+ this.featureProcessingVersions = featureProcessingVersions;
this.serviceRequirements = serviceRequirements;
}
diff --git a/features/core/src/test/java/org/apache/karaf/features/internal/service/BlacklistTest.java b/features/core/src/test/java/org/apache/karaf/features/internal/service/BlacklistTest.java
index 6c5d7e2..34fc55f 100644
--- a/features/core/src/test/java/org/apache/karaf/features/internal/service/BlacklistTest.java
+++ b/features/core/src/test/java/org/apache/karaf/features/internal/service/BlacklistTest.java
@@ -83,7 +83,7 @@ public class BlacklistTest {
fos.write(blacklistClause.getBytes("UTF-8"));
}
RepositoryImpl features = new RepositoryImpl(uri, true);
- FeaturesServiceConfig config = new FeaturesServiceConfig(null, FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE, FeaturesService.DEFAULT_BUNDLE_UPDATE_RANGE, null, 1, 0, 0, blacklistedProperties.toURI().toString(), null, null);
+ FeaturesServiceConfig config = new FeaturesServiceConfig(null, FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE, FeaturesService.DEFAULT_BUNDLE_UPDATE_RANGE, null, 1, 0, 0, blacklistedProperties.toURI().toString(), null, null, null);
features.processFeatures(new FeaturesProcessorImpl(config));
return Arrays.stream(features.getFeatures());
}
diff --git a/features/core/src/test/java/org/apache/karaf/features/internal/service/FeaturesProcessorTest.java b/features/core/src/test/java/org/apache/karaf/features/internal/service/FeaturesProcessorTest.java
index e73e7d1..45955b2 100644
--- a/features/core/src/test/java/org/apache/karaf/features/internal/service/FeaturesProcessorTest.java
+++ b/features/core/src/test/java/org/apache/karaf/features/internal/service/FeaturesProcessorTest.java
@@ -18,7 +18,9 @@
*/
package org.apache.karaf.features.internal.service;
+import java.io.FileWriter;
import java.net.URI;
+import java.util.Properties;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
@@ -89,7 +91,7 @@ public class FeaturesProcessorTest {
public void readingLegacyOverrides() {
FeaturesProcessorImpl processor = new FeaturesProcessorImpl(new FeaturesServiceConfig(
"file:src/test/resources/org/apache/karaf/features/internal/service/overrides2.properties",
- null, null));
+ null, null, null));
FeaturesProcessing instructions = processor.getInstructions();
BundleReplacements bundleReplacements = instructions.getBundleReplacements();
@@ -116,7 +118,7 @@ public class FeaturesProcessorTest {
FeaturesProcessorImpl processor = new FeaturesProcessorImpl(new FeaturesServiceConfig(
null,
"file:src/test/resources/org/apache/karaf/features/internal/service/blacklisted2.properties",
- null));
+ null, null));
FeaturesProcessing instructions = processor.getInstructions();
Blacklist blacklist = instructions.getBlacklist();
@@ -136,7 +138,7 @@ public class FeaturesProcessorTest {
public void blacklistingRepositories() {
FeaturesProcessorImpl processor = new FeaturesProcessorImpl(new FeaturesServiceConfig(
null, null,
- "file:src/test/resources/org/apache/karaf/features/internal/service/fpi01.xml"));
+ "file:src/test/resources/org/apache/karaf/features/internal/service/fpi01.xml", null));
URI uri = URI.create("file:src/test/resources/org/apache/karaf/features/internal/service/fp01.xml");
RepositoryImpl repo = (RepositoryImpl) new RepositoryCacheImpl(processor).create(uri, true);
assertThat(repo.getRepositories().length, equalTo(3));
@@ -150,7 +152,7 @@ public class FeaturesProcessorTest {
public void blacklistingFeatures() {
FeaturesProcessorImpl processor = new FeaturesProcessorImpl(new FeaturesServiceConfig(
null, null,
- "file:src/test/resources/org/apache/karaf/features/internal/service/fpi01.xml"));
+ "file:src/test/resources/org/apache/karaf/features/internal/service/fpi01.xml", null));
URI uri = URI.create("file:src/test/resources/org/apache/karaf/features/internal/service/fp02.xml");
RepositoryImpl repo = (RepositoryImpl) new RepositoryCacheImpl(processor).create(uri, true);
@@ -166,7 +168,7 @@ public class FeaturesProcessorTest {
public void blacklistingBundles() {
FeaturesProcessorImpl processor = new FeaturesProcessorImpl(new FeaturesServiceConfig(
null, null,
- "file:src/test/resources/org/apache/karaf/features/internal/service/fpi01.xml"));
+ "file:src/test/resources/org/apache/karaf/features/internal/service/fpi01.xml", null));
URI uri = URI.create("file:src/test/resources/org/apache/karaf/features/internal/service/fp03.xml");
RepositoryImpl repo = (RepositoryImpl) new RepositoryCacheImpl(processor).create(uri, true);
@@ -182,7 +184,7 @@ public class FeaturesProcessorTest {
public void overridingBundles() {
FeaturesProcessorImpl processor = new FeaturesProcessorImpl(new FeaturesServiceConfig(
null, null,
- "file:src/test/resources/org/apache/karaf/features/internal/service/fpi02.xml"));
+ "file:src/test/resources/org/apache/karaf/features/internal/service/fpi02.xml", null));
URI uri = URI.create("file:src/test/resources/org/apache/karaf/features/internal/service/fp03.xml");
RepositoryImpl repo = (RepositoryImpl) new RepositoryCacheImpl(processor).create(uri, true);
@@ -202,6 +204,24 @@ public class FeaturesProcessorTest {
}
@Test
+ public void resolvePlaceholders() throws Exception {
+ Properties props = new Properties();
+ props.put("version.jclouds", "1.9");
+ props.put("version.commons-io", "2.5");
+ props.store(new FileWriter("target/versions.properties"), null);
+
+ FeaturesProcessorImpl processor = new FeaturesProcessorImpl(new FeaturesServiceConfig(
+ null, null,
+ "file:src/test/resources/org/apache/karaf/features/internal/service/fpi03.xml",
+ "file:target/versions.properties"));
+
+ assertThat(processor.getInstructions().getBlacklistedRepositories().get(0),
+ equalTo("mvn:org.jclouds/jclouds-features/1.9/xml/features"));
+ assertThat(processor.getInstructions().getBundleReplacements().getOverrideBundles().get(0).getReplacement(),
+ equalTo("mvn:commons-io/commons-io/2.5"));
+ }
+
+ @Test
public void serializeWithComments() {
FeaturesProcessingSerializer serializer = new FeaturesProcessingSerializer();
FeaturesProcessing featuresProcessing = new FeaturesProcessing();
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/service/fpi03.xml b/features/core/src/test/resources/org/apache/karaf/features/internal/service/fpi03.xml
new file mode 100644
index 0000000..4528fbd
--- /dev/null
+++ b/features/core/src/test/resources/org/apache/karaf/features/internal/service/fpi03.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<featuresProcessing xmlns="http://karaf.apache.org/xmlns/features-processing/v1.0.0">
+
+ <blacklistedRepositories>
+ <repository>mvn:org.jclouds/jclouds-features/${version.jclouds}/xml/features</repository>
+ </blacklistedRepositories>
+
+ <bundleReplacements>
+ <bundle replacement="mvn:commons-io/commons-io/${version.commons-io}" />
+ </bundleReplacements>
+
+</featuresProcessing>
diff --git a/pom.xml b/pom.xml
index 4f218d5..81106e9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -273,6 +273,7 @@
<pax.exam.version>4.11.0</pax.exam.version>
<pax.logging.version>1.10.1</pax.logging.version>
<pax.base.version>1.5.0</pax.base.version>
+ <pax.swissbox.version>1.8.2</pax.swissbox.version>
<pax.url.version>2.5.3</pax.url.version>
<pax.web.version>6.1.0-SNAPSHOT</pax.web.version>
<pax.tinybundle.version>2.1.1</pax.tinybundle.version>
@@ -1246,6 +1247,16 @@
<version>${pax.base.version}</version>
</dependency>
<dependency>
+ <groupId>org.ops4j.base</groupId>
+ <artifactId>ops4j-base-util-property</artifactId>
+ <version>${pax.base.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.ops4j.base</groupId>
+ <artifactId>ops4j-base-util-collections</artifactId>
+ <version>${pax.base.version}</version>
+ </dependency>
+ <dependency>
<groupId>org.ops4j.pax.url</groupId>
<artifactId>pax-url-aether</artifactId>
<version>${pax.url.version}</version>
@@ -1305,6 +1316,11 @@
</exclusions>
</dependency>
<dependency>
+ <groupId>org.ops4j.pax.swissbox</groupId>
+ <artifactId>pax-swissbox-property</artifactId>
+ <version>${pax.swissbox.version}</version>
+ </dependency>
+ <dependency>
<groupId>org.ops4j.pax.url</groupId>
<artifactId>pax-url-wrap</artifactId>
<version>${pax.url.version}</version>
diff --git a/profile/src/main/java/org/apache/karaf/profile/assembly/Builder.java b/profile/src/main/java/org/apache/karaf/profile/assembly/Builder.java
index 274d535..4a5603c 100644
--- a/profile/src/main/java/org/apache/karaf/profile/assembly/Builder.java
+++ b/profile/src/main/java/org/apache/karaf/profile/assembly/Builder.java
@@ -906,7 +906,7 @@ public class Builder {
// now we can configure blacklisting features processor which may have already defined (in XML)
// configuration for bundle replacements or feature overrides.
// we'll add overrides from profiles later.
- FeaturesProcessorImpl processor = new FeaturesProcessorImpl(existingProcessorDefinitionURI, blacklist, new HashSet<>());
+ FeaturesProcessorImpl processor = new FeaturesProcessorImpl(existingProcessorDefinitionURI, null, blacklist, new HashSet<>());
//
// Propagate feature installation from repositories
--
To stop receiving notification emails like this one, please contact
"commits@karaf.apache.org" <co...@karaf.apache.org>.