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 2014/05/19 21:16:24 UTC
[1/5] git commit: [KARAF-2988] Add support for prerequisites on
features
Repository: karaf
Updated Branches:
refs/heads/master b46bd22bc -> cde64ae2a
[KARAF-2988] Add support for prerequisites on features
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/cde64ae2
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/cde64ae2
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/cde64ae2
Branch: refs/heads/master
Commit: cde64ae2ab110c4659bc23255c7c2dc1d3eb03f0
Parents: c1a6ca7
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Mon May 19 21:14:50 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Mon May 19 21:16:05 2014 +0200
----------------------------------------------------------------------
assemblies/apache-karaf/pom.xml | 1 +
.../enterprise/src/main/feature/feature.xml | 2 +
assemblies/features/framework/pom.xml | 23 ----
.../framework/src/main/feature/feature.xml | 1 -
.../etc/org.apache.karaf.features.repos.cfg | 1 +
.../standard/src/main/feature/feature.xml | 9 +-
.../org/apache/karaf/features/Dependency.java | 2 +
.../features/internal/model/Dependency.java | 23 +++-
.../karaf/features/internal/model/Feature.java | 13 +-
.../features/internal/region/Subsystem.java | 76 ++++++++----
.../internal/region/SubsystemResolver.java | 38 +++---
.../features/internal/service/Deployer.java | 64 +++++++++-
.../internal/service/FeaturesServiceImpl.java | 19 ++-
.../karaf/features/karaf-features-1.3.0.xsd | 2 +
.../apache/karaf/features/RepositoryTest.java | 4 +-
.../features/internal/region/SubsystemTest.java | 42 +++----
.../features/internal/service/DeployerTest.java | 118 +++++++++++++++++++
.../features/internal/service/data2/a100.mf | 5 +
.../features/internal/service/data2/b100.mf | 5 +
.../internal/service/data2/features.xml | 30 +++++
20 files changed, 373 insertions(+), 105 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/cde64ae2/assemblies/apache-karaf/pom.xml
----------------------------------------------------------------------
diff --git a/assemblies/apache-karaf/pom.xml b/assemblies/apache-karaf/pom.xml
index a799b0a..6b721ed 100644
--- a/assemblies/apache-karaf/pom.xml
+++ b/assemblies/apache-karaf/pom.xml
@@ -160,6 +160,7 @@
<feature>wrapper</feature>
</installedFeatures>
<bootFeatures>
+ <feature>wrap</feature>
<feature>aries-blueprint</feature>
<feature>shell</feature>
<feature>shell-compat</feature>
http://git-wip-us.apache.org/repos/asf/karaf/blob/cde64ae2/assemblies/features/enterprise/src/main/feature/feature.xml
----------------------------------------------------------------------
diff --git a/assemblies/features/enterprise/src/main/feature/feature.xml b/assemblies/features/enterprise/src/main/feature/feature.xml
index ad2ecf6..e38335c 100644
--- a/assemblies/features/enterprise/src/main/feature/feature.xml
+++ b/assemblies/features/enterprise/src/main/feature/feature.xml
@@ -111,6 +111,7 @@
<feature name="hibernate" description="Hibernate 4.2.x JPA persistence engine support" version="${hibernate42.version}">
<details>Enable Hibernate 4.2.x as persistence engine.</details>
+ <feature prerequisite="true">wrap</feature>
<feature>transaction</feature>
<feature>http</feature>
<bundle dependency="true">mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.antlr/${antlr.bundle.version}</bundle>
@@ -137,6 +138,7 @@
<feature name="hibernate" description="Hibernate 4.3.x JPA persistence engine support" version="${hibernate43.version}">
<details>Enable Hibernate 4.3.x as persistence engine.</details>
+ <feature prerequisite="true">wrap</feature>
<feature>transaction</feature>
<feature>http</feature>
<bundle dependency="true" start-level="30">mvn:org.hibernate.javax.persistence/hibernate-jpa-2.1-api/1.0.0.Final</bundle>
http://git-wip-us.apache.org/repos/asf/karaf/blob/cde64ae2/assemblies/features/framework/pom.xml
----------------------------------------------------------------------
diff --git a/assemblies/features/framework/pom.xml b/assemblies/features/framework/pom.xml
index 51dc83a..3e8ba86 100644
--- a/assemblies/features/framework/pom.xml
+++ b/assemblies/features/framework/pom.xml
@@ -139,29 +139,6 @@
</exclusion>
</exclusions>
</dependency>
- <dependency>
- <groupId>org.ops4j.pax.url</groupId>
- <artifactId>pax-url-wrap</artifactId>
- <classifier>uber</classifier>
- <exclusions>
- <exclusion>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.ops4j.base</groupId>
- <artifactId>ops4j-base-net</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.ops4j.pax.swissbox</groupId>
- <artifactId>pax-swissbox-bnd</artifactId>
- </exclusion>
- <exclusion>
- <groupId>org.ops4j.pax.url</groupId>
- <artifactId>pax-url-commons</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
<dependency>
<groupId>org.apache.felix</groupId>
http://git-wip-us.apache.org/repos/asf/karaf/blob/cde64ae2/assemblies/features/framework/src/main/feature/feature.xml
----------------------------------------------------------------------
diff --git a/assemblies/features/framework/src/main/feature/feature.xml b/assemblies/features/framework/src/main/feature/feature.xml
index 51b97e5..3b79d62 100644
--- a/assemblies/features/framework/src/main/feature/feature.xml
+++ b/assemblies/features/framework/src/main/feature/feature.xml
@@ -24,7 +24,6 @@
<feature version="${project.version}" description="Karaf core feature" name="framework">
<!-- mvn: and wrap: url handlers -->
<bundle start="true" start-level="5">mvn:org.ops4j.pax.url/pax-url-aether/${pax.url.version}</bundle>
- <bundle start="true" start-level="5">mvn:org.ops4j.pax.url/pax-url-wrap/${pax.url.version}/jar/uber</bundle>
<!-- logging -->
<bundle start="true" start-level="8">mvn:org.ops4j.pax.logging/pax-logging-api/${pax.logging.version}</bundle>
<bundle start="true" start-level="8">mvn:org.ops4j.pax.logging/pax-logging-service/${pax.logging.version}</bundle>
http://git-wip-us.apache.org/repos/asf/karaf/blob/cde64ae2/assemblies/features/framework/src/main/resources/resources/etc/org.apache.karaf.features.repos.cfg
----------------------------------------------------------------------
diff --git a/assemblies/features/framework/src/main/resources/resources/etc/org.apache.karaf.features.repos.cfg b/assemblies/features/framework/src/main/resources/resources/etc/org.apache.karaf.features.repos.cfg
index 7574897..df7ea32 100644
--- a/assemblies/features/framework/src/main/resources/resources/etc/org.apache.karaf.features.repos.cfg
+++ b/assemblies/features/framework/src/main/resources/resources/etc/org.apache.karaf.features.repos.cfg
@@ -22,6 +22,7 @@
# It could be directly installed using feature:repo-add command
#
+enterprise = mvn:org.apache.karaf.features/enterprise/${version}/xml/features
cellar = mvn:org.apache.karaf.cellar/apache-karaf-cellar/${version}/xml/features
camel = mvn:org.apache.camel.karaf/apache-camel/${version}/xml/features
camel-extras = mvn:org.apache-extras.camel-extra.karaf/camel-extra/${version}/xml/features
http://git-wip-us.apache.org/repos/asf/karaf/blob/cde64ae2/assemblies/features/standard/src/main/feature/feature.xml
----------------------------------------------------------------------
diff --git a/assemblies/features/standard/src/main/feature/feature.xml b/assemblies/features/standard/src/main/feature/feature.xml
index c02dea0..9f68409 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -84,9 +84,12 @@
</feature>
<feature name="deployer" description="Karaf Deployer" version="${project.version}">
- <bundle start="true" start-level="24">mvn:org.apache.karaf.deployer/org.apache.karaf.deployer.wrap/${project.version}</bundle>
<bundle start="true" start-level="26">mvn:org.apache.karaf.deployer/org.apache.karaf.deployer.features/${project.version}</bundle>
<conditional>
+ <condition>wrap</condition>
+ <bundle start="true" start-level="24">mvn:org.apache.karaf.deployer/org.apache.karaf.deployer.wrap/${project.version}</bundle>
+ </conditional>
+ <conditional>
<condition>req:osgi.extender;filter:="(&(osgi.extender=osgi.blueprint)(version>=1.0))"</condition>
<bundle start="true" start-level="24">mvn:org.apache.karaf.deployer/org.apache.karaf.deployer.blueprint/${project.version}</bundle>
</conditional>
@@ -295,4 +298,8 @@
<bundle>mvn:org.apache.aries.blueprint/org.apache.aries.blueprint.webosgi/${aries.blueprint.web.version}</bundle>
</feature>
+ <feature name="wrap" description="Wrap URL handler">
+ <bundle start="true" start-level="5">mvn:org.ops4j.pax.url/pax-url-wrap/${pax.url.version}/jar/uber</bundle>
+ </feature>
+
</features>
http://git-wip-us.apache.org/repos/asf/karaf/blob/cde64ae2/features/core/src/main/java/org/apache/karaf/features/Dependency.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/Dependency.java b/features/core/src/main/java/org/apache/karaf/features/Dependency.java
index 5e019c7..421df19 100644
--- a/features/core/src/main/java/org/apache/karaf/features/Dependency.java
+++ b/features/core/src/main/java/org/apache/karaf/features/Dependency.java
@@ -23,4 +23,6 @@ public interface Dependency {
String getVersion();
+ boolean isPrerequisite();
+
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/cde64ae2/features/core/src/main/java/org/apache/karaf/features/internal/model/Dependency.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/model/Dependency.java b/features/core/src/main/java/org/apache/karaf/features/internal/model/Dependency.java
index b099f28..2a4d8dd 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/model/Dependency.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/model/Dependency.java
@@ -42,13 +42,15 @@ import javax.xml.bind.annotation.XmlValue;
* </pre>
*/
@XmlAccessorType(XmlAccessType.FIELD)
-@XmlType(name = "dependency", propOrder = {"value"})
+@XmlType(name = "dependency", propOrder = {"name"})
public class Dependency implements org.apache.karaf.features.Dependency {
@XmlValue
- protected String value;
+ protected String name;
@XmlAttribute
protected String version;
+ @XmlAttribute
+ protected boolean prerequisite;
/**
* Feature name should be non empty string.
@@ -57,7 +59,7 @@ public class Dependency implements org.apache.karaf.features.Dependency {
* {@link String }
*/
public String getName() {
- return value;
+ return name;
}
/**
@@ -67,7 +69,7 @@ public class Dependency implements org.apache.karaf.features.Dependency {
* {@link String }
*/
public void setName(String value) {
- this.value = value;
+ this.name = value;
}
/**
@@ -78,7 +80,7 @@ public class Dependency implements org.apache.karaf.features.Dependency {
*/
public String getVersion() {
if (version == null) {
- return "0.0.0";
+ return Feature.DEFAULT_VERSION;
} else {
return version;
}
@@ -94,8 +96,17 @@ public class Dependency implements org.apache.karaf.features.Dependency {
this.version = value;
}
+ @Override
+ public boolean isPrerequisite() {
+ return prerequisite;
+ }
+
+ public void setPrerequisite(boolean prerequisite) {
+ this.prerequisite = prerequisite;
+ }
+
public String toString() {
- return getName() + Feature.SPLIT_FOR_NAME_AND_VERSION + getVersion();
+ return getName() + Feature.VERSION_SEPARATOR + getVersion();
}
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/cde64ae2/features/core/src/main/java/org/apache/karaf/features/internal/model/Feature.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/model/Feature.java b/features/core/src/main/java/org/apache/karaf/features/internal/model/Feature.java
index 6cf3820..4d3eb12 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/model/Feature.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/model/Feature.java
@@ -30,7 +30,6 @@ import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import org.apache.felix.utils.version.VersionCleaner;
-import org.apache.felix.utils.version.VersionTable;
/**
@@ -78,7 +77,7 @@ import org.apache.felix.utils.version.VersionTable;
})
public class Feature extends Content implements org.apache.karaf.features.Feature {
- public static final String SPLIT_FOR_NAME_AND_VERSION = "/";
+ public static final String VERSION_SEPARATOR = "/";
public static final String DEFAULT_VERSION = "0.0.0";
@@ -114,10 +113,10 @@ public class Feature extends Content implements org.apache.karaf.features.Featur
public static org.apache.karaf.features.Feature valueOf(String str) {
- if (str.contains(SPLIT_FOR_NAME_AND_VERSION)) {
- String strName = str.substring(0, str.indexOf(SPLIT_FOR_NAME_AND_VERSION));
- String strVersion = str.substring(str.indexOf(SPLIT_FOR_NAME_AND_VERSION)
- + SPLIT_FOR_NAME_AND_VERSION.length(), str.length());
+ if (str.contains(VERSION_SEPARATOR)) {
+ String strName = str.substring(0, str.indexOf(VERSION_SEPARATOR));
+ String strVersion = str.substring(str.indexOf(VERSION_SEPARATOR)
+ + VERSION_SEPARATOR.length(), str.length());
return new Feature(strName, strVersion);
} else {
return new Feature(str);
@@ -128,7 +127,7 @@ public class Feature extends Content implements org.apache.karaf.features.Featur
public String getId() {
- return getName() + SPLIT_FOR_NAME_AND_VERSION + getVersion();
+ return getName() + VERSION_SEPARATOR + getVersion();
}
/**
http://git-wip-us.apache.org/repos/asf/karaf/blob/cde64ae2/features/core/src/main/java/org/apache/karaf/features/internal/region/Subsystem.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/region/Subsystem.java b/features/core/src/main/java/org/apache/karaf/features/internal/region/Subsystem.java
index bfe170e..f64bc0f 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/region/Subsystem.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/region/Subsystem.java
@@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -85,11 +86,11 @@ public class Subsystem extends ResourceImpl {
private final boolean acceptDependencies;
private final Subsystem parent;
private final Feature feature;
- private final List<Subsystem> children = new ArrayList<Subsystem>();
+ private final List<Subsystem> children = new ArrayList<>();
private final Map<String, Set<String>> importPolicy;
private final Map<String, Set<String>> exportPolicy;
- private final List<Resource> installable = new ArrayList<Resource>();
- private final Map<String, DependencyInfo> dependencies = new HashMap<String, DependencyInfo>();
+ private final List<Resource> installable = new ArrayList<>();
+ private final Map<String, DependencyInfo> dependencies = new HashMap<>();
public Subsystem(String name) {
super(name, TYPE_SUBSYSTEM, Version.emptyVersion);
@@ -117,8 +118,8 @@ public class Subsystem extends ResourceImpl {
this.exportPolicy = SHARE_ALL_POLICY;
}
- Map<String, String> dirs = new HashMap<String, String>();
- Map<String, Object> attrs = new HashMap<String, Object>();
+ Map<String, String> dirs = new HashMap<>();
+ Map<String, Object> attrs = new HashMap<>();
attrs.put(IDENTITY_NAMESPACE, feature.getName());
attrs.put(CAPABILITY_TYPE_ATTRIBUTE, TYPE_FEATURE);
attrs.put(CAPABILITY_VERSION_ATTRIBUTE, new VersionRange(VersionTable.getVersion(feature.getVersion()), true));
@@ -205,7 +206,7 @@ public class Subsystem extends ResourceImpl {
}
public Map<String, BundleInfo> getBundleInfos() {
- Map<String, BundleInfo> infos = new HashMap<String, BundleInfo>();
+ Map<String, BundleInfo> infos = new HashMap<>();
for (DependencyInfo di : dependencies.values()) {
infos.put(di.getLocation(), di);
}
@@ -213,14 +214,20 @@ public class Subsystem extends ResourceImpl {
}
@SuppressWarnings("InfiniteLoopStatement")
- public void preResolve(Collection<Feature> features,
- DownloadManager manager,
- Set<String> overrides,
- String featureResolutionRange) throws Exception {
+ public void build(Collection<Feature> features) throws Exception {
for (Subsystem child : children) {
- child.preResolve(features, manager, overrides, featureResolutionRange);
+ child.build(features);
}
- List<Requirement> processed = new ArrayList<Requirement>();
+ if (feature != null) {
+ for (Dependency dep : feature.getDependencies()) {
+ Subsystem ss = this;
+ while (!ss.isAcceptDependencies()) {
+ ss = ss.getParent();
+ }
+ ss.requireFeature(dep.getName(), dep.getVersion());
+ }
+ }
+ List<Requirement> processed = new ArrayList<>();
while (true) {
List<Requirement> requirements = getRequirements(IDENTITY_NAMESPACE);
requirements.removeAll(processed);
@@ -240,7 +247,7 @@ public class Subsystem extends ResourceImpl {
Subsystem fs = getChild(ssName);
if (fs == null) {
fs = new Subsystem(ssName, feature, this);
- fs.preResolve(features, manager, overrides, featureResolutionRange);
+ fs.build(features);
installable.add(fs);
children.add(fs);
}
@@ -251,10 +258,38 @@ public class Subsystem extends ResourceImpl {
processed.add(requirement);
}
}
+ }
+
+ public Set<String> collectPrerequisites() {
+ Set<String> prereqs = new HashSet<>();
+ doCollectPrerequisites(prereqs);
+ return prereqs;
+ }
+
+ private void doCollectPrerequisites(Set<String> prereqs) {
+ for (Subsystem child : children) {
+ child.doCollectPrerequisites(prereqs);
+ }
+ if (feature != null) {
+ for (Dependency dep : feature.getDependencies()) {
+ if (dep.isPrerequisite()) {
+ prereqs.add(dep.toString());
+ }
+ }
+ }
+ }
+
+ @SuppressWarnings("InfiniteLoopStatement")
+ public void downloadBundles(DownloadManager manager,
+ Set<String> overrides,
+ String featureResolutionRange) throws Exception {
+ for (Subsystem child : children) {
+ child.downloadBundles(manager, overrides, featureResolutionRange);
+ }
if (feature != null) {
- final Map<String, ResourceImpl> bundles = new ConcurrentHashMap<String, ResourceImpl>();
+ final Map<String, ResourceImpl> bundles = new ConcurrentHashMap<>();
final Downloader downloader = manager.createDownloader();
- final Map<BundleInfo, Conditional> infos = new HashMap<BundleInfo, Conditional>();
+ final Map<BundleInfo, Conditional> infos = new HashMap<>();
for (Conditional cond : feature.getConditional()) {
for (final BundleInfo bi : cond.getBundles()) {
infos.put(bi, cond);
@@ -286,15 +321,8 @@ public class Subsystem extends ResourceImpl {
}
downloader.await();
Overrides.override(bundles, overrides);
- for (Dependency dep : feature.getDependencies()) {
- Subsystem ss = this;
- while (!ss.isAcceptDependencies()) {
- ss = ss.getParent();
- }
- ss.requireFeature(dep.getName(), dep.getVersion());
- }
// Add conditionals
- Map<Conditional, Resource> resConds = new HashMap<Conditional, Resource>();
+ Map<Conditional, Resource> resConds = new HashMap<>();
for (Conditional cond : feature.getConditional()) {
FeatureResource resCond = FeatureResource.build(feature, cond, featureResolutionRange, bundles);
addIdentityRequirement(this, resCond, false);
@@ -382,7 +410,7 @@ public class Subsystem extends ResourceImpl {
}
Map<String, Set<String>> createPolicy(List<? extends ScopeFilter> filters) {
- Map<String, Set<String>> policy = new HashMap<String, Set<String>>();
+ Map<String, Set<String>> policy = new HashMap<>();
for (ScopeFilter filter : filters) {
addToMapSet(policy, filter.getNamespace(), filter.getFilter());
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/cde64ae2/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolver.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolver.java b/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolver.java
index 2682e58..f8f7bca 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolver.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolver.java
@@ -32,7 +32,6 @@ import org.apache.karaf.features.Feature;
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.download.simple.SimpleDownloader;
import org.apache.karaf.features.internal.resolver.CapabilityImpl;
import org.apache.karaf.features.internal.resolver.CapabilitySet;
import org.apache.karaf.features.internal.resolver.ResourceBuilder;
@@ -76,6 +75,7 @@ public class SubsystemResolver {
private Map<Resource, List<Wire>> wiring;
// Cached computed results
+ private ResourceImpl environmentResource;
private Map<String, String> flatSubsystemsMap;
private Map<String, Set<Resource>> bundlesPerRegions;
private Map<Resource, String> bundles;
@@ -85,21 +85,14 @@ public class SubsystemResolver {
private Map<String, Map<String, BundleInfo>> bundleInfos;
- public SubsystemResolver() {
- this(new SimpleDownloader());
- }
-
public SubsystemResolver(DownloadManager manager) {
this.manager = manager;
}
- public Map<Resource, List<Wire>> resolve(
+ public void prepare(
Collection<Feature> allFeatures,
Map<String, Set<String>> features,
- Map<String, Set<BundleRevision>> system,
- Set<String> overrides,
- String featureResolutionRange,
- org.osgi.service.repository.Repository globalRepository
+ Map<String, Set<BundleRevision>> system
) throws Exception {
// Build subsystems on the fly
for (Map.Entry<String, Set<String>> entry : features.entrySet()) {
@@ -128,13 +121,13 @@ public class SubsystemResolver {
}
}
if (root == null) {
- return Collections.emptyMap();
+ return;
}
+
// Pre-resolve
- root.preResolve(allFeatures, manager, overrides, featureResolutionRange);
+ root.build(allFeatures);
// Add system resources
- ResourceImpl environmentResource = null;
BundleRevision sysBundleRev = null;
boolean hasEeCap = false;
for (Map.Entry<String, Set<BundleRevision>> entry : system.entrySet()) {
@@ -157,7 +150,7 @@ public class SubsystemResolver {
Map<String, String> headers = new DictionaryAsMap<>(res.getBundle().getHeaders());
Resource tmp = ResourceBuilder.build(res.getBundle().getLocation(), headers);
for (Capability cap : tmp.getCapabilities(ServiceNamespace.SERVICE_NAMESPACE)) {
- dummy.addCapability(new CapabilityImpl(dummy, cap.getNamespace(), cap.getDirectives() ,cap.getAttributes()));
+ dummy.addCapability(new CapabilityImpl(dummy, cap.getNamespace(), cap.getDirectives(), cap.getAttributes()));
}
ss.addSystemResource(res);
for (Capability cap : res.getCapabilities(null)) {
@@ -177,6 +170,23 @@ public class SubsystemResolver {
environmentResource.addCapabilities(ResourceBuilder.parseCapability(environmentResource, provideCaps));
root.addSystemResource(environmentResource);
}
+ }
+
+ public Set<String> collectPrerequisites() throws Exception {
+ return root.collectPrerequisites();
+ }
+
+ public Map<Resource, List<Wire>> resolve(
+ Set<String> overrides,
+ String featureResolutionRange,
+ final org.osgi.service.repository.Repository globalRepository
+ ) throws Exception {
+ if (root == null) {
+ return Collections.emptyMap();
+ }
+
+ // Download bundles
+ root.downloadBundles(manager, overrides, featureResolutionRange);
// Populate digraph and resolve
digraph = new StandardRegionDigraph(null, null);
http://git-wip-us.apache.org/repos/asf/karaf/blob/cde64ae2/features/core/src/main/java/org/apache/karaf/features/internal/service/Deployer.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/Deployer.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/Deployer.java
index 5a1cd02..d80fe3d 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/Deployer.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/Deployer.java
@@ -34,6 +34,7 @@ import java.util.TreeMap;
import java.util.TreeSet;
import org.apache.felix.utils.version.VersionRange;
+import org.apache.felix.utils.version.VersionTable;
import org.apache.karaf.features.BundleInfo;
import org.apache.karaf.features.Feature;
import org.apache.karaf.features.FeatureEvent;
@@ -58,7 +59,6 @@ import org.osgi.framework.startlevel.BundleStartLevel;
import org.osgi.framework.wiring.BundleRevision;
import org.osgi.framework.wiring.BundleWire;
import org.osgi.framework.wiring.BundleWiring;
-import org.osgi.resource.Capability;
import org.osgi.resource.Resource;
import org.osgi.resource.Wire;
import org.osgi.service.repository.Repository;
@@ -118,6 +118,18 @@ public class Deployer {
void replaceDigraph(Map<String, Map<String,Map<String,Set<String>>>> policies, Map<String, Set<Long>> bundles) throws BundleException, InvalidSyntaxException;
}
+ public static class PartialDeploymentException extends Exception {
+ private final Set<String> missing;
+
+ public PartialDeploymentException(Set<String> missing) {
+ this.missing = missing;
+ }
+
+ public Set<String> getMissing() {
+ return missing;
+ }
+ }
+
static class DeploymentState {
State state;
Bundle serviceBundle;
@@ -191,10 +203,56 @@ public class Deployer {
// TODO: bundles
SubsystemResolver resolver = new SubsystemResolver(manager);
- resolver.resolve(
+ resolver.prepare(
dstate.features.values(),
request.requestedFeatures,
- apply(unmanagedBundles, adapt(BundleRevision.class)),
+ apply(unmanagedBundles, adapt(BundleRevision.class))
+ );
+ Set<String> prereqs = resolver.collectPrerequisites();
+ if (!prereqs.isEmpty()) {
+ for (Iterator<String> iterator = prereqs.iterator(); iterator.hasNext(); ) {
+ String prereq = iterator.next();
+ String[] parts = prereq.split("/");
+ VersionRange range;
+ if (parts[1].equals("0.0.0")) {
+ range = VersionRange.ANY_VERSION;
+ } else if (!parts[1].startsWith("[") && !parts[1].startsWith("(")) {
+ range = new VersionRange(Macro.transform(request.featureResolutionRange, parts[1]));
+ } else {
+ range = new VersionRange(parts[1]);
+ }
+ boolean found = false;
+ for (Set<String> featureSet : dstate.state.installedFeatures.values()) {
+ for (String feature : featureSet) {
+ String[] p = feature.split("/");
+ found = parts[0].equals(p[0]) && range.contains(VersionTable.getVersion(p[1]));
+ if (found) break;
+ }
+ if (found) break;
+ }
+ if (found) {
+ iterator.remove();
+ }
+ }
+ }
+ if (!prereqs.isEmpty()) {
+ DeploymentRequest newRequest = new DeploymentRequest();
+ newRequest.bundleUpdateRange = request.bundleUpdateRange;
+ newRequest.featureResolutionRange = request.featureResolutionRange;
+ newRequest.globalRepository = request.globalRepository;
+ newRequest.options = request.options;
+ newRequest.overrides = request.overrides;
+ newRequest.requestedFeatures = copy(dstate.state.requestedFeatures);
+ for (String prereq : prereqs) {
+ addToMapSet(newRequest.requestedFeatures, ROOT_REGION, prereq);
+ }
+ newRequest.stateChanges = Collections.emptyMap();
+ newRequest.updateSnaphots = request.updateSnaphots;
+ deploy(dstate, newRequest);
+ throw new PartialDeploymentException(prereqs);
+ }
+
+ resolver.resolve(
request.overrides,
request.featureResolutionRange,
request.globalRepository);
http://git-wip-us.apache.org/repos/asf/karaf/blob/cde64ae2/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
index f0f0677..03686aa 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/FeaturesServiceImpl.java
@@ -908,9 +908,22 @@ public class FeaturesServiceImpl implements FeaturesService, Deployer.DeployCall
EnumSet<Option> options // installation options
) throws Exception {
- Deployer.DeploymentState dstate = getDeploymentState(state);
- Deployer.DeploymentRequest request = getDeploymentRequest(requestedFeatures, stateChanges, options);
- new Deployer(new SimpleDownloader(), this).deploy(dstate, request);
+ Set<String> prereqs = new HashSet<>();
+ while (true) {
+ try {
+ Deployer.DeploymentState dstate = getDeploymentState(state);
+ Deployer.DeploymentRequest request = getDeploymentRequest(requestedFeatures, stateChanges, options);
+ new Deployer(new SimpleDownloader(), this).deploy(dstate, request);
+ break;
+ } catch (Deployer.PartialDeploymentException e) {
+ if (!prereqs.containsAll(e.getMissing())) {
+ prereqs.addAll(e.getMissing());
+ state = copyState();
+ } else {
+ throw new Exception("Deployment aborted due to loop in missing prerequisites: " + e.getMissing());
+ }
+ }
+ }
}
public void print(String message, boolean verbose) {
http://git-wip-us.apache.org/repos/asf/karaf/blob/cde64ae2/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.3.0.xsd
----------------------------------------------------------------------
diff --git a/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.3.0.xsd b/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.3.0.xsd
index e28f05f..4d6e81d 100644
--- a/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.3.0.xsd
+++ b/features/core/src/main/resources/org/apache/karaf/features/karaf-features-1.3.0.xsd
@@ -165,6 +165,7 @@ Dependency of feature.
<xs:simpleContent>
<xs:extension base="tns:featureName">
<xs:attribute name="version" type="xs:string" default="0.0.0" />
+ <xs:attribute name="prerequisite" type="xs:boolean" default="false"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
@@ -219,6 +220,7 @@ Additional requirements of this feature.
</xs:annotation>
<xs:simpleContent>
<xs:extension base="xs:string">
+ <xs:attribute name="prerequisite" type="xs:boolean" default="false"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
http://git-wip-us.apache.org/repos/asf/karaf/blob/cde64ae2/features/core/src/test/java/org/apache/karaf/features/RepositoryTest.java
----------------------------------------------------------------------
diff --git a/features/core/src/test/java/org/apache/karaf/features/RepositoryTest.java b/features/core/src/test/java/org/apache/karaf/features/RepositoryTest.java
index 164dc79..c8da238 100644
--- a/features/core/src/test/java/org/apache/karaf/features/RepositoryTest.java
+++ b/features/core/src/test/java/org/apache/karaf/features/RepositoryTest.java
@@ -56,7 +56,7 @@ public class RepositoryTest extends TestCase {
assertEquals(0, features[1].getConfigurations().size());
assertNotNull(features[1].getDependencies());
assertEquals(1, features[1].getDependencies().size());
- assertEquals("f1" + org.apache.karaf.features.internal.model.Feature.SPLIT_FOR_NAME_AND_VERSION + org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION, features[1].getDependencies().get(0).toString());
+ assertEquals("f1" + org.apache.karaf.features.internal.model.Feature.VERSION_SEPARATOR + org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION, features[1].getDependencies().get(0).toString());
assertNotNull(features[1].getBundles());
assertEquals(1, features[1].getBundles().size());
assertEquals("b3", features[1].getBundles().get(0).getLocation());
@@ -98,7 +98,7 @@ public class RepositoryTest extends TestCase {
assertEquals(0, features[1].getConfigurations().size());
assertNotNull(features[1].getDependencies());
assertEquals(1, features[1].getDependencies().size());
- assertEquals("f1" + org.apache.karaf.features.internal.model.Feature.SPLIT_FOR_NAME_AND_VERSION + org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION, features[1].getDependencies().get(0).toString());
+ assertEquals("f1" + org.apache.karaf.features.internal.model.Feature.VERSION_SEPARATOR + org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION, features[1].getDependencies().get(0).toString());
assertNotNull(features[1].getBundles());
assertEquals(1, features[1].getBundles().size());
assertEquals("b3", features[1].getBundles().get(0).getLocation());
http://git-wip-us.apache.org/repos/asf/karaf/blob/cde64ae2/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java
----------------------------------------------------------------------
diff --git a/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java b/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java
index 42c66d7..e6b5b8f 100644
--- a/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java
+++ b/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java
@@ -54,10 +54,10 @@ public class SubsystemTest {
addToMapSet(expected, "root/apps1", "b/1.0.0");
SubsystemResolver resolver = new SubsystemResolver(new TestDownloadManager(getClass(), "data1"));
- resolver.resolve(Arrays.asList(repo.getFeatures()),
+ resolver.prepare(Arrays.asList(repo.getFeatures()),
features,
- Collections.<String, Set<BundleRevision>>emptyMap(),
- Collections.<String>emptySet(),
+ Collections.<String, Set<BundleRevision>>emptyMap());
+ resolver.resolve(Collections.<String>emptySet(),
FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE,
null);
@@ -85,10 +85,10 @@ public class SubsystemTest {
addToMapSet(expected, "root/apps2#f1", "a/1.0.0");
SubsystemResolver resolver = new SubsystemResolver(new TestDownloadManager(getClass(), "data2"));
- resolver.resolve(Arrays.asList(repo.getFeatures()),
+ resolver.prepare(Arrays.asList(repo.getFeatures()),
features,
- Collections.<String, Set<BundleRevision>>emptyMap(),
- Collections.<String>emptySet(),
+ Collections.<String, Set<BundleRevision>>emptyMap());
+ resolver.resolve(Collections.<String>emptySet(),
FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE,
null);
@@ -106,10 +106,10 @@ public class SubsystemTest {
addToMapSet(expected, "root/apps1", "a/1.0.1");
SubsystemResolver resolver = new SubsystemResolver(new TestDownloadManager(getClass(), "data3"));
- resolver.resolve(Arrays.asList(repo.getFeatures()),
+ resolver.prepare(Arrays.asList(repo.getFeatures()),
features,
- Collections.<String, Set<BundleRevision>>emptyMap(),
- Collections.singleton("b"),
+ Collections.<String, Set<BundleRevision>>emptyMap());
+ resolver.resolve(Collections.singleton("b"),
FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE,
null);
@@ -126,12 +126,12 @@ public class SubsystemTest {
addToMapSet(expected, "root/apps1", "a/1.0.0");
SubsystemResolver resolver = new SubsystemResolver(new TestDownloadManager(getClass(), "data4"));
- resolver.resolve(Arrays.asList(repo.getFeatures()),
- features,
- Collections.<String, Set<BundleRevision>>emptyMap(),
- Collections.<String>emptySet(),
- FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE,
- null);
+ resolver.prepare(Arrays.asList(repo.getFeatures()),
+ features,
+ Collections.<String, Set<BundleRevision>>emptyMap());
+ resolver.resolve(Collections.<String>emptySet(),
+ FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE,
+ null);
verify(resolver, expected);
}
@@ -148,12 +148,12 @@ public class SubsystemTest {
addToMapSet(expected, "root/apps1", "b/1.0.0");
SubsystemResolver resolver = new SubsystemResolver(new TestDownloadManager(getClass(), "data4"));
- resolver.resolve(Arrays.asList(repo.getFeatures()),
- features,
- Collections.<String, Set<BundleRevision>>emptyMap(),
- Collections.<String>emptySet(),
- FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE,
- null);
+ resolver.prepare(Arrays.asList(repo.getFeatures()),
+ features,
+ Collections.<String, Set<BundleRevision>>emptyMap());
+ resolver.resolve(Collections.<String>emptySet(),
+ FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE,
+ null);
verify(resolver, expected);
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/cde64ae2/features/core/src/test/java/org/apache/karaf/features/internal/service/DeployerTest.java
----------------------------------------------------------------------
diff --git a/features/core/src/test/java/org/apache/karaf/features/internal/service/DeployerTest.java b/features/core/src/test/java/org/apache/karaf/features/internal/service/DeployerTest.java
index 42c7c49..723df3b 100644
--- a/features/core/src/test/java/org/apache/karaf/features/internal/service/DeployerTest.java
+++ b/features/core/src/test/java/org/apache/karaf/features/internal/service/DeployerTest.java
@@ -44,6 +44,7 @@ import static org.apache.karaf.features.FeaturesService.*;
import static org.apache.karaf.features.internal.util.MapUtils.addToMapSet;
import static org.easymock.EasyMock.anyInt;
import static org.easymock.EasyMock.anyObject;
+import static org.junit.Assert.fail;
public class DeployerTest {
@@ -259,6 +260,123 @@ public class DeployerTest {
EasyMock.verify(callback);
}
+ @Test
+ public void testPrerequisite() throws Exception {
+
+ String dataDir = "data2";
+
+ TestDownloadManager manager = new TestDownloadManager(getClass(), dataDir);
+
+ RepositoryImpl repo = new RepositoryImpl(getClass().getResource(dataDir + "/features.xml").toURI());
+ repo.load(true);
+ Feature f1 = repo.getFeatures()[0];
+ Feature f2 = repo.getFeatures()[1];
+
+ Bundle serviceBundle1 = createTestBundle(1, Bundle.ACTIVE, dataDir, "a100");
+ Bundle serviceBundle2 = createTestBundle(2, Bundle.ACTIVE, dataDir, "b100");
+
+ Deployer.DeployCallback callback = EasyMock.createMock(Deployer.DeployCallback.class);
+ Deployer deployer = new Deployer(manager, callback);
+
+ callback.print(EasyMock.anyString(), EasyMock.anyBoolean());
+ EasyMock.expectLastCall().anyTimes();
+ callback.installBundle(EasyMock.eq(ROOT_REGION), EasyMock.eq("a100"), EasyMock.<InputStream>anyObject());
+ EasyMock.expectLastCall().andReturn(serviceBundle1);
+ callback.replaceDigraph(EasyMock.<Map<String, Map<String, Map<String, Set<String>>>>>anyObject(),
+ EasyMock.<Map<String, Set<Long>>>anyObject());
+ EasyMock.expectLastCall();
+ callback.saveState(EasyMock.<State>anyObject());
+ EasyMock.expectLastCall();
+ callback.installFeatureConfigs(f1);
+ EasyMock.expectLastCall();
+ callback.resolveBundles(EasyMock.<Set<Bundle>>anyObject());
+ EasyMock.expectLastCall();
+ callback.callListeners(EasyMock.<FeatureEvent>anyObject());
+ EasyMock.expectLastCall();
+
+ EasyMock.replay(callback);
+
+ Deployer.DeploymentState dstate = new Deployer.DeploymentState();
+ dstate.state = new State();
+ dstate.bundles = new HashMap<>();
+ dstate.bundlesPerRegion = new HashMap<>();
+ dstate.features = new HashMap<>();
+ dstate.features.put(f1.getId(), f1);
+ dstate.features.put(f2.getId(), f2);
+ dstate.filtersPerRegion = new HashMap<>();
+ dstate.filtersPerRegion.put(ROOT_REGION, new HashMap<String, Map<String, Set<String>>>());
+
+ Deployer.DeploymentRequest request = new Deployer.DeploymentRequest();
+ request.bundleUpdateRange = DEFAULT_BUNDLE_UPDATE_RANGE;
+ request.featureResolutionRange = DEFAULT_FEATURE_RESOLUTION_RANGE;
+ request.globalRepository = null;
+ request.options = EnumSet.noneOf(Option.class);
+ request.overrides = Collections.emptySet();
+ request.stateChanges = Collections.emptyMap();
+ request.updateSnaphots = UPDATE_SNAPSHOTS_NONE;
+ request.requestedFeatures = new HashMap<>();
+ addToMapSet(request.requestedFeatures, ROOT_REGION, f2.getName());
+
+ try {
+ deployer.deploy(dstate, request);
+ fail("Should have thrown an exception");
+ } catch (Deployer.PartialDeploymentException e) {
+ // ok
+ }
+
+ EasyMock.verify(callback);
+
+ EasyMock.reset(callback);
+
+ callback.print(EasyMock.anyString(), EasyMock.anyBoolean());
+ EasyMock.expectLastCall().anyTimes();
+ callback.installBundle(EasyMock.eq(ROOT_REGION), EasyMock.eq("b100"), EasyMock.<InputStream>anyObject());
+ EasyMock.expectLastCall().andReturn(serviceBundle2);
+ callback.replaceDigraph(EasyMock.<Map<String, Map<String, Map<String, Set<String>>>>>anyObject(),
+ EasyMock.<Map<String, Set<Long>>>anyObject());
+ EasyMock.expectLastCall();
+ callback.saveState(EasyMock.<State>anyObject());
+ EasyMock.expectLastCall();
+ callback.installFeatureConfigs(f2);
+ EasyMock.expectLastCall();
+ callback.resolveBundles(EasyMock.<Set<Bundle>>anyObject());
+ EasyMock.expectLastCall();
+ callback.callListeners(EasyMock.<FeatureEvent>anyObject());
+ EasyMock.expectLastCall();
+
+ EasyMock.replay(callback);
+
+ dstate = new Deployer.DeploymentState();
+ dstate.state = new State();
+ addToMapSet(dstate.state.installedFeatures, ROOT_REGION, f1.getId());
+ dstate.state.stateFeatures.put(ROOT_REGION, Collections.singletonMap(f1.getId(), "Started"));
+ addToMapSet(dstate.state.managedBundles, ROOT_REGION, serviceBundle1.getBundleId());
+ dstate.bundles = new HashMap<>();
+ dstate.bundles.put(serviceBundle1.getBundleId(), serviceBundle1);
+ dstate.bundlesPerRegion = new HashMap<>();
+ addToMapSet(dstate.bundlesPerRegion, ROOT_REGION, serviceBundle1.getBundleId());
+ dstate.features = new HashMap<>();
+ dstate.features.put(f1.getId(), f1);
+ dstate.features.put(f2.getId(), f2);
+ dstate.filtersPerRegion = new HashMap<>();
+ dstate.filtersPerRegion.put(ROOT_REGION, new HashMap<String, Map<String, Set<String>>>());
+
+ request = new Deployer.DeploymentRequest();
+ request.bundleUpdateRange = DEFAULT_BUNDLE_UPDATE_RANGE;
+ request.featureResolutionRange = DEFAULT_FEATURE_RESOLUTION_RANGE;
+ request.globalRepository = null;
+ request.options = EnumSet.noneOf(Option.class);
+ request.overrides = Collections.emptySet();
+ request.stateChanges = Collections.emptyMap();
+ request.updateSnaphots = UPDATE_SNAPSHOTS_NONE;
+ request.requestedFeatures = new HashMap<>();
+ addToMapSet(request.requestedFeatures, ROOT_REGION, f2.getName());
+
+ deployer.deploy(dstate, request);
+
+ EasyMock.verify(callback);
+ }
+
private TestBundle createTestBundle(long bundleId, int state, String dir, String name) throws IOException, BundleException {
URL loc = getClass().getResource(dir + "/" + name + ".mf");
Manifest man = new Manifest(loc.openStream());
http://git-wip-us.apache.org/repos/asf/karaf/blob/cde64ae2/features/core/src/test/resources/org/apache/karaf/features/internal/service/data2/a100.mf
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/service/data2/a100.mf b/features/core/src/test/resources/org/apache/karaf/features/internal/service/data2/a100.mf
new file mode 100644
index 0000000..20a7811
--- /dev/null
+++ b/features/core/src/test/resources/org/apache/karaf/features/internal/service/data2/a100.mf
@@ -0,0 +1,5 @@
+Manifest-Version: 1
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: a
+Bundle-Version: 1.0.0
+
http://git-wip-us.apache.org/repos/asf/karaf/blob/cde64ae2/features/core/src/test/resources/org/apache/karaf/features/internal/service/data2/b100.mf
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/service/data2/b100.mf b/features/core/src/test/resources/org/apache/karaf/features/internal/service/data2/b100.mf
new file mode 100644
index 0000000..dc96158
--- /dev/null
+++ b/features/core/src/test/resources/org/apache/karaf/features/internal/service/data2/b100.mf
@@ -0,0 +1,5 @@
+Manifest-Version: 1
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: b
+Bundle-Version: 1.0.0
+
http://git-wip-us.apache.org/repos/asf/karaf/blob/cde64ae2/features/core/src/test/resources/org/apache/karaf/features/internal/service/data2/features.xml
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/service/data2/features.xml b/features/core/src/test/resources/org/apache/karaf/features/internal/service/data2/features.xml
new file mode 100644
index 0000000..a70c692
--- /dev/null
+++ b/features/core/src/test/resources/org/apache/karaf/features/internal/service/data2/features.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.
+
+-->
+<features name="test" xmlns="http://karaf.apache.org/xmlns/features/v1.3.0">
+
+ <feature name="f1" version="1.0.0">
+ <bundle>a100</bundle>
+ </feature>
+
+ <feature name="f2" version="1.0.0">
+ <feature prerequisite="true">f1</feature>
+ <bundle>b100</bundle>
+ </feature>
+
+</features>
\ No newline at end of file
[5/5] git commit: Fix manual and command help generation
Posted by gn...@apache.org.
Fix manual and command help generation
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/49aeec2b
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/49aeec2b
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/49aeec2b
Branch: refs/heads/master
Commit: 49aeec2b73d3227ba78fb6bef7e025aafced8577
Parents: 0cf070d
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Mon May 19 10:53:45 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Mon May 19 21:16:05 2014 +0200
----------------------------------------------------------------------
manual/pom.xml | 41 +---------
.../WEB-INF/scalate/layouts/default.scaml | 2 +-
manual/src/main/webapp/manual.conf | 2 +-
pom.xml | 6 +-
.../commands/AbstractCommandHelpPrinter.java | 85 ++++++++++++++++++++
.../tooling/commands/CommandHelpPrinter.java | 6 +-
.../commands/DocBookCommandHelpPrinter.java | 74 ++++++++++-------
.../tooling/commands/GenerateHelpMojo.java | 11 +--
.../commands/UserConfCommandHelpPrinter.java | 67 +++++++++------
9 files changed, 186 insertions(+), 108 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/49aeec2b/manual/pom.xml
----------------------------------------------------------------------
diff --git a/manual/pom.xml b/manual/pom.xml
index db14ba7..768fd21 100644
--- a/manual/pom.xml
+++ b/manual/pom.xml
@@ -167,7 +167,7 @@
</dependency>
<dependency>
<groupId>org.apache.karaf.shell</groupId>
- <artifactId>org.apache.karaf.shell.console</artifactId>
+ <artifactId>org.apache.karaf.shell.core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
@@ -176,32 +176,17 @@
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.apache.karaf.log</groupId>
- <artifactId>org.apache.karaf.log.command</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
<groupId>org.apache.karaf.obr</groupId>
<artifactId>org.apache.karaf.obr.core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.apache.karaf.obr</groupId>
- <artifactId>org.apache.karaf.obr.command</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
<groupId>org.apache.karaf.bundle</groupId>
<artifactId>org.apache.karaf.bundle.core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.karaf.bundle</groupId>
- <artifactId>org.apache.karaf.bundle.command</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.karaf.bundle</groupId>
<artifactId>org.apache.karaf.bundle.springstate</artifactId>
<version>${project.version}</version>
</dependency>
@@ -211,16 +196,6 @@
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.apache.karaf.service</groupId>
- <artifactId>org.apache.karaf.service.command</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.karaf.system</groupId>
- <artifactId>org.apache.karaf.system.command</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
<groupId>org.apache.karaf.system</groupId>
<artifactId>org.apache.karaf.system.core</artifactId>
<version>${project.version}</version>
@@ -232,32 +207,22 @@
</dependency>
<dependency>
<groupId>org.apache.karaf.web</groupId>
- <artifactId>org.apache.karaf.web.command</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.karaf.web</groupId>
<artifactId>org.apache.karaf.web.core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.karaf.wrapper</groupId>
- <artifactId>org.apache.karaf.wrapper.command</artifactId>
- <version>${project.version}</version>
- </dependency>
- <dependency>
- <groupId>org.apache.karaf.wrapper</groupId>
<artifactId>org.apache.karaf.wrapper.core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.karaf.instance</groupId>
- <artifactId>org.apache.karaf.instance.command</artifactId>
+ <artifactId>org.apache.karaf.instance.core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.karaf.diagnostic</groupId>
- <artifactId>org.apache.karaf.diagnostic.command</artifactId>
+ <artifactId>org.apache.karaf.diagnostic.core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
http://git-wip-us.apache.org/repos/asf/karaf/blob/49aeec2b/manual/src/main/webapp/WEB-INF/scalate/layouts/default.scaml
----------------------------------------------------------------------
diff --git a/manual/src/main/webapp/WEB-INF/scalate/layouts/default.scaml b/manual/src/main/webapp/WEB-INF/scalate/layouts/default.scaml
index c88ba58..e4f22cd 100644
--- a/manual/src/main/webapp/WEB-INF/scalate/layouts/default.scaml
+++ b/manual/src/main/webapp/WEB-INF/scalate/layouts/default.scaml
@@ -98,7 +98,7 @@
%td#cell-3-2
#footer
#site-footer
- © 2008-2011 The Apache Software Foundation
+ © 2008-2014 The Apache Software Foundation
%br
Apache Karaf, Karaf, Apache, the Apache feather logo, and the Apache Karaf project logo are trademarks of The Apache Software Foundation.
%td#cell-3-3
http://git-wip-us.apache.org/repos/asf/karaf/blob/49aeec2b/manual/src/main/webapp/manual.conf
----------------------------------------------------------------------
diff --git a/manual/src/main/webapp/manual.conf b/manual/src/main/webapp/manual.conf
index db428da..de21749 100644
--- a/manual/src/main/webapp/manual.conf
+++ b/manual/src/main/webapp/manual.conf
@@ -15,7 +15,7 @@ Users' Guide
{div}
{div:class=copyright-section}
-Copyright 2011 The Apache Software Foundation
+Copyright 2008-2014 The Apache Software Foundation
The PDF format of the Karaf Manual has been generated by Prince XML (http://www.princexml.com).
{div}
http://git-wip-us.apache.org/repos/asf/karaf/blob/49aeec2b/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 8aeb574..fe95af6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2250,9 +2250,9 @@
<exclude>**/foo</exclude>
<exclude>**/org.ops4j.pax.exam.TestContainerFactory</exclude>
<!--manual resources -->
- <exclude>manual/**/*.css</exclude>
- <exclude>manual/**/*.ssp</exclude>
- <exclude>manual/**/*.conf</exclude>
+ <exclude>**/*.css</exclude>
+ <exclude>**/*.ssp</exclude>
+ <exclude>**/*.conf</exclude>
<!-- test manifests -->
<exclude>**/*.mf</exclude>
<!-- test json files -->
http://git-wip-us.apache.org/repos/asf/karaf/blob/49aeec2b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/AbstractCommandHelpPrinter.java
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/AbstractCommandHelpPrinter.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/AbstractCommandHelpPrinter.java
new file mode 100644
index 0000000..dee1eb9
--- /dev/null
+++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/AbstractCommandHelpPrinter.java
@@ -0,0 +1,85 @@
+/**
+ * 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.commands;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+
+public abstract class AbstractCommandHelpPrinter implements CommandHelpPrinter {
+
+ protected Argument replaceDefaultArgument(Field field, Argument argument) {
+ if (Argument.DEFAULT.equals(argument.name())) {
+ final Argument delegate = argument;
+ final String name = field.getName();
+ argument = new Argument() {
+ public String name() {
+ return name;
+ }
+
+ public String description() {
+ return delegate.description();
+ }
+
+ public boolean required() {
+ return delegate.required();
+ }
+
+ public int index() {
+ return delegate.index();
+ }
+
+ public boolean multiValued() {
+ return delegate.multiValued();
+ }
+
+ public String valueToShowInHelp() {
+ return delegate.valueToShowInHelp();
+ }
+
+ public Class<? extends Annotation> annotationType() {
+ return delegate.annotationType();
+ }
+ };
+ }
+ return argument;
+ }
+
+ protected Object getDefaultValue(Action action, Field field) {
+ try {
+ field.setAccessible(true);
+ return field.get(action);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ protected String getDefaultValueString(Object o) {
+ if (o != null
+ && (!(o instanceof Boolean) || ((Boolean) o))
+ && (!(o instanceof Number) || ((Number) o).doubleValue() != 0.0)) {
+ return o.toString();
+ } else {
+ return null;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/karaf/blob/49aeec2b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/CommandHelpPrinter.java
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/CommandHelpPrinter.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/CommandHelpPrinter.java
index 5fae3db..f255434 100644
--- a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/CommandHelpPrinter.java
+++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/CommandHelpPrinter.java
@@ -22,19 +22,17 @@ import java.io.PrintStream;
import java.util.Map;
import java.util.Set;
-import org.apache.karaf.shell.commands.Action;
-import org.apache.karaf.shell.commands.meta.ActionMetaData;
+import org.apache.karaf.shell.api.action.Action;
public interface CommandHelpPrinter {
/**
* Print help for a single action to the out stream
*
* @param action
- * @param actionMeta
* @param out stream to write to
* @param includeHelpOption include the help option in the doc
*/
- void printHelp(Action action, ActionMetaData actionMeta, PrintStream out, boolean includeHelpOption);
+ void printHelp(Action action, PrintStream out, boolean includeHelpOption);
/**
* Print the overview of all given commands to the out stream
http://git-wip-us.apache.org/repos/asf/karaf/blob/49aeec2b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/DocBookCommandHelpPrinter.java
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/DocBookCommandHelpPrinter.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/DocBookCommandHelpPrinter.java
index 7467b9a..d40841c 100644
--- a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/DocBookCommandHelpPrinter.java
+++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/DocBookCommandHelpPrinter.java
@@ -21,38 +21,53 @@ package org.apache.karaf.tooling.commands;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import org.apache.karaf.shell.commands.Action;
-import org.apache.karaf.shell.commands.Argument;
-import org.apache.karaf.shell.commands.Command;
-import org.apache.karaf.shell.commands.HelpOption;
-import org.apache.karaf.shell.commands.Option;
-import org.apache.karaf.shell.commands.meta.ActionMetaData;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.impl.action.command.HelpOption;
+
/**
* Prints documentation in docbook syntax
*/
-public class DocBookCommandHelpPrinter implements CommandHelpPrinter {
+public class DocBookCommandHelpPrinter extends AbstractCommandHelpPrinter {
@Override
- public void printHelp(Action action, ActionMetaData actionMeta, PrintStream out, boolean includeHelpOption) {
-
- Map<Option, Field> optionsMap = actionMeta.getOptions();
- Map<Argument, Field> argsMap = actionMeta.getArguments();
+ public void printHelp(Action action, PrintStream out, boolean includeHelpOption) {
Command command = action.getClass().getAnnotation(Command.class);
- List<Argument> arguments = new ArrayList<Argument>(argsMap.keySet());
- Collections.sort(arguments, new Comparator<Argument>() {
- public int compare(Argument o1, Argument o2) {
- return Integer.valueOf(o1.index()).compareTo(Integer.valueOf(o2.index()));
+ Set<Option> options = new HashSet<>();
+ List<Argument> arguments = new ArrayList<Argument>();
+ Map<Argument, Field> argFields = new HashMap<>();
+ Map<Option, Field> optFields = new HashMap<>();
+ for (Class<?> type = action.getClass(); type != null; type = type.getSuperclass()) {
+ for (Field field : type.getDeclaredFields()) {
+ Option option = field.getAnnotation(Option.class);
+ if (option != null) {
+ options.add(option);
+ }
+
+ Argument argument = field.getAnnotation(Argument.class);
+ if (argument != null) {
+ argument = replaceDefaultArgument(field, argument);
+ argFields.put(argument, field);
+ int index = argument.index();
+ while (arguments.size() <= index) {
+ arguments.add(null);
+ }
+ if (arguments.get(index) != null) {
+ throw new IllegalArgumentException("Duplicate argument index: " + index + " on Action " + action.getClass().getName());
+ }
+ arguments.set(index, argument);
+ }
}
- });
- Set<Option> options = new HashSet<Option>(optionsMap.keySet());
+ }
if (includeHelpOption)
options.add(HelpOption.HELP);
@@ -92,10 +107,14 @@ public class DocBookCommandHelpPrinter implements CommandHelpPrinter {
out.println(" <td>" + argument.name() + "</td>");
String description = argument.description();
if (!argument.required()) {
- Object o = actionMeta.getDefaultValue(action, argument);
- String defaultValue = actionMeta.getDefaultValueString(o);
- if (defaultValue != null) {
- description += " (defaults to " + o.toString() + ")";
+ if (argument.valueToShowInHelp() != null && argument.valueToShowInHelp().length() != 0) {
+ if (Argument.DEFAULT_STRING.equals(argument.valueToShowInHelp())) {
+ Object o = getDefaultValue(action, argFields.get(argument));
+ String defaultValue = getDefaultValueString(o);
+ if (defaultValue != null) {
+ description += " (defaults to " + o.toString() + ")";
+ }
+ }
}
}
out.println(" <td>" + description + "</td>");
@@ -117,8 +136,8 @@ public class DocBookCommandHelpPrinter implements CommandHelpPrinter {
for (String alias : option.aliases()) {
opt += ", " + alias;
}
- Object o = actionMeta.getDefaultValue(action, option);
- String defaultValue = actionMeta.getDefaultValueString(o);
+ Object o = getDefaultValue(action, optFields.get(option));
+ String defaultValue = getDefaultValueString(o);
if (defaultValue != null) {
description += " (defaults to " + o.toString() + ")";
}
@@ -132,12 +151,11 @@ public class DocBookCommandHelpPrinter implements CommandHelpPrinter {
out.println(" </section>");
}
- String desc = actionMeta.getDetailedDescription();
- if (desc != null) {
+ if (command.detailedDescription().length() > 0) {
out.println(" <section>");
out.println(" <title>Details</title>");
out.println(" <para>");
- out.println(desc);
+ out.println(command.detailedDescription());
out.println(" </para>");
out.println(" </section>");
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/49aeec2b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/GenerateHelpMojo.java
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/GenerateHelpMojo.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/GenerateHelpMojo.java
index 7416640..b75a766 100644
--- a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/GenerateHelpMojo.java
+++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/GenerateHelpMojo.java
@@ -30,10 +30,8 @@ import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
-import org.apache.karaf.shell.commands.Action;
-import org.apache.karaf.shell.commands.Command;
-import org.apache.karaf.shell.commands.meta.ActionMetaData;
-import org.apache.karaf.shell.commands.meta.ActionMetaDataFactory;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Command;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
@@ -118,8 +116,7 @@ public class GenerateHelpMojo extends AbstractMojo {
for (Class<?> clazz : classes) {
try {
Action action = (Action) clazz.newInstance();
- ActionMetaData meta = new ActionMetaDataFactory().create(action.getClass());
- Command cmd = meta.getCommand();
+ Command cmd = clazz.getAnnotation(Command.class);
// skip the *-help command
if (cmd.scope().equals("*")) continue;
@@ -127,7 +124,7 @@ public class GenerateHelpMojo extends AbstractMojo {
File output = new File(targetFolder, cmd.scope() + "-" + cmd.name() + "." + commandSuffix);
FileOutputStream outStream = new FileOutputStream(output);
PrintStream out = new PrintStream(outStream);
- helpPrinter.printHelp(action, meta, out, includeHelpOption);
+ helpPrinter.printHelp(action, out, includeHelpOption);
out.close();
outStream.close();
http://git-wip-us.apache.org/repos/asf/karaf/blob/49aeec2b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/UserConfCommandHelpPrinter.java
----------------------------------------------------------------------
diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/UserConfCommandHelpPrinter.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/UserConfCommandHelpPrinter.java
index 468386f..59f7bd9 100644
--- a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/UserConfCommandHelpPrinter.java
+++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/commands/UserConfCommandHelpPrinter.java
@@ -21,37 +21,53 @@ package org.apache.karaf.tooling.commands;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import org.apache.karaf.shell.commands.Action;
-import org.apache.karaf.shell.commands.Argument;
-import org.apache.karaf.shell.commands.Command;
-import org.apache.karaf.shell.commands.HelpOption;
-import org.apache.karaf.shell.commands.Option;
-import org.apache.karaf.shell.commands.meta.ActionMetaData;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.impl.action.command.HelpOption;
+
/**
* Prints documentation in wiki syntax
*/
-public class UserConfCommandHelpPrinter implements CommandHelpPrinter {
+public class UserConfCommandHelpPrinter extends AbstractCommandHelpPrinter {
@Override
- public void printHelp(Action action, ActionMetaData actionMeta, PrintStream out, boolean includeHelpOption) {
- Map<Option, Field> optionsMap = actionMeta.getOptions();
- Map<Argument, Field> argsMap = actionMeta.getArguments();
- Command command = actionMeta.getCommand();
- List<Argument> arguments = new ArrayList<Argument>(argsMap.keySet());
- Collections.sort(arguments, new Comparator<Argument>() {
- public int compare(Argument o1, Argument o2) {
- return Integer.valueOf(o1.index()).compareTo(Integer.valueOf(o2.index()));
+ public void printHelp(Action action, PrintStream out, boolean includeHelpOption) {
+ Command command = action.getClass().getAnnotation(Command.class);
+ Set<Option> options = new HashSet<>();
+ List<Argument> arguments = new ArrayList<Argument>();
+ Map<Argument, Field> argFields = new HashMap<>();
+ Map<Option, Field> optFields = new HashMap<>();
+ for (Class<?> type = action.getClass(); type != null; type = type.getSuperclass()) {
+ for (Field field : type.getDeclaredFields()) {
+ Option option = field.getAnnotation(Option.class);
+ if (option != null) {
+ options.add(option);
+ }
+
+ Argument argument = field.getAnnotation(Argument.class);
+ if (argument != null) {
+ argument = replaceDefaultArgument(field, argument);
+ argFields.put(argument, field);
+ int index = argument.index();
+ while (arguments.size() <= index) {
+ arguments.add(null);
+ }
+ if (arguments.get(index) != null) {
+ throw new IllegalArgumentException("Duplicate argument index: " + index + " on Action " + action.getClass().getName());
+ }
+ arguments.set(index, argument);
+ }
}
- });
- Set<Option> options = new HashSet<Option>(optionsMap.keySet());
+ }
if (includeHelpOption)
options.add(HelpOption.HELP);
@@ -83,8 +99,8 @@ public class UserConfCommandHelpPrinter implements CommandHelpPrinter {
for (Argument argument : arguments) {
String description = argument.description();
if (!argument.required()) {
- Object o = actionMeta.getDefaultValue(action, argument);
- String defaultValue = actionMeta.getDefaultValueString(o);
+ Object o = getDefaultValue(action, argFields.get(argument));
+ String defaultValue = getDefaultValueString(o);
if (defaultValue != null) {
description += " (defaults to " + o.toString() + ")";
}
@@ -102,8 +118,8 @@ public class UserConfCommandHelpPrinter implements CommandHelpPrinter {
for (String alias : option.aliases()) {
opt += ", " + alias;
}
- Object o = actionMeta.getDefaultValue(action, option);
- String defaultValue = actionMeta.getDefaultValueString(o);
+ Object o = getDefaultValue(action, optFields.get(option));
+ String defaultValue = getDefaultValueString(o);
if (defaultValue != null) {
desc += " (defaults to " + defaultValue + ")";
}
@@ -111,10 +127,9 @@ public class UserConfCommandHelpPrinter implements CommandHelpPrinter {
}
out.println();
}
- String detailedDesc = actionMeta.getDetailedDescription();
- if (detailedDesc != null) {
+ if (command.detailedDescription().length() > 0) {
out.println("h2. Details");
- out.println(detailedDesc);
+ out.println(command.detailedDescription());
}
out.println();
}
[4/5] git commit: Fix web module activator
Posted by gn...@apache.org.
Fix web module activator
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/c1a6ca74
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/c1a6ca74
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/c1a6ca74
Branch: refs/heads/master
Commit: c1a6ca7454d15e19462f92dcdd75b98df4d641ad
Parents: 1d60fca
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Mon May 19 11:56:14 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Mon May 19 21:16:05 2014 +0200
----------------------------------------------------------------------
web/src/main/java/org/apache/karaf/web/internal/osgi/Activator.java | 1 -
1 file changed, 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/c1a6ca74/web/src/main/java/org/apache/karaf/web/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/web/src/main/java/org/apache/karaf/web/internal/osgi/Activator.java b/web/src/main/java/org/apache/karaf/web/internal/osgi/Activator.java
index 4709e81..7a1681c 100644
--- a/web/src/main/java/org/apache/karaf/web/internal/osgi/Activator.java
+++ b/web/src/main/java/org/apache/karaf/web/internal/osgi/Activator.java
@@ -32,7 +32,6 @@ import org.ops4j.pax.web.service.spi.WebListener;
requires = @RequireService(WarManager.class),
provides = @ProvideService(WebContainerService.class)
)
-@Managed("org.apache.karaf.shell")
public class Activator extends BaseActivator {
@Override
[2/5] git commit: Clean some warnings and unused code in features/core
Posted by gn...@apache.org.
Clean some warnings and unused code in features/core
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/1d60fca2
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/1d60fca2
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/1d60fca2
Branch: refs/heads/master
Commit: 1d60fca2132cc2b204ac43efb1a9fcc589e16e82
Parents: 49aeec2
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Mon May 19 11:17:50 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Mon May 19 21:16:05 2014 +0200
----------------------------------------------------------------------
.../internal/resolver/ResourceUtils.java | 4 +--
.../internal/resolver/SimpleFilter.java | 7 +++--
.../internal/service/BootFeaturesInstaller.java | 29 ++------------------
3 files changed, 9 insertions(+), 31 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/1d60fca2/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResourceUtils.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResourceUtils.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResourceUtils.java
index d6cfe1d..d3f5527 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResourceUtils.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/ResourceUtils.java
@@ -79,8 +79,8 @@ public final class ResourceUtils {
}
public static void addIdentityRequirement(ResourceImpl resource, String name, String type, String range) {
- Map<String, String> dirs = new HashMap<String, String>();
- Map<String, Object> attrs = new HashMap<String, Object>();
+ Map<String, String> dirs = new HashMap<>();
+ Map<String, Object> attrs = new HashMap<>();
if (name != null) {
attrs.put(IDENTITY_NAMESPACE, name);
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/1d60fca2/features/core/src/main/java/org/apache/karaf/features/internal/resolver/SimpleFilter.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/SimpleFilter.java b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/SimpleFilter.java
index 1e2a48c..2354519 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/resolver/SimpleFilter.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/resolver/SimpleFilter.java
@@ -57,8 +57,9 @@ public class SimpleFilter {
return op;
}
+ @SuppressWarnings("unchecked")
public String toString() {
- String s = null;
+ String s;
switch (op) {
case AND:
s = "(&" + toString((List) value) + ")";
@@ -138,6 +139,7 @@ public class SimpleFilter {
return o.toString();
}
+ @SuppressWarnings("unchecked")
public static SimpleFilter parse(String filter) {
int idx = skipWhitespace(filter, 0);
@@ -446,11 +448,12 @@ public class SimpleFilter {
* @param attrs Map of attributes to convert to a filter.
* @return A filter corresponding to the attributes.
*/
+ @SuppressWarnings("unchecked")
public static SimpleFilter convert(Map<String, Object> attrs) {
// Rather than building a filter string to be parsed into a SimpleFilter,
// we will just create the parsed SimpleFilter directly.
- List<SimpleFilter> filters = new ArrayList<SimpleFilter>();
+ List<SimpleFilter> filters = new ArrayList<>();
for (Entry<String, Object> entry : attrs.entrySet()) {
if (entry.getValue() instanceof VersionRange) {
http://git-wip-us.apache.org/repos/asf/karaf/blob/1d60fca2/features/core/src/main/java/org/apache/karaf/features/internal/service/BootFeaturesInstaller.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/service/BootFeaturesInstaller.java b/features/core/src/main/java/org/apache/karaf/features/internal/service/BootFeaturesInstaller.java
index 81e6a3a..f8283dd 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/service/BootFeaturesInstaller.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/service/BootFeaturesInstaller.java
@@ -28,7 +28,6 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.karaf.features.BootFinished;
-import org.apache.karaf.features.Feature;
import org.apache.karaf.features.FeaturesService;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
@@ -36,8 +35,6 @@ import org.slf4j.LoggerFactory;
public class BootFeaturesInstaller {
- public static final String VERSION_PREFIX = "version=";
-
private static final Logger LOGGER = LoggerFactory.getLogger(BootFeaturesInstaller.class);
private final FeaturesServiceImpl featuresService;
@@ -115,32 +112,10 @@ public class BootFeaturesInstaller {
}
}
- /**
- * @param featureSt either feature name or <featurename>;version=<version>
- * @return feature matching the feature string
- * @throws Exception
- */
- private Feature getFeature(String featureSt) throws Exception {
- String[] parts = featureSt.trim().split(";");
- String featureName = parts[0];
- String featureVersion = null;
- for (String part : parts) {
- // if the part starts with "version=" it contains the version info
- if (part.startsWith(VERSION_PREFIX)) {
- featureVersion = part.substring(VERSION_PREFIX.length());
- }
- }
- if (featureVersion == null) {
- // no version specified - use default version
- featureVersion = org.apache.karaf.features.internal.model.Feature.DEFAULT_VERSION;
- }
- return featuresService.getFeature(featureName, featureVersion);
- }
-
protected List<Set<String>> parseBootFeatures(String bootFeatures) {
Pattern pattern = Pattern.compile("(\\((.+))\\),|.+");
Matcher matcher = pattern.matcher(bootFeatures);
- List<Set<String>> result = new ArrayList<Set<String>>();
+ List<Set<String>> result = new ArrayList<>();
while (matcher.find()) {
String group = matcher.group(2) != null ? matcher.group(2) : matcher.group();
result.add(parseFeatureList(group));
@@ -149,7 +124,7 @@ public class BootFeaturesInstaller {
}
protected Set<String> parseFeatureList(String group) {
- HashSet<String> features = new HashSet<String>();
+ HashSet<String> features = new HashSet<>();
for (String feature : Arrays.asList(group.trim().split("\\s*,\\s*"))) {
if (feature.length() > 0) {
features.add(feature);
[3/5] git commit: Fix scr feature to add missing capabilities
Posted by gn...@apache.org.
Fix scr feature to add missing capabilities
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/0cf070d4
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/0cf070d4
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/0cf070d4
Branch: refs/heads/master
Commit: 0cf070d4f56348110b74234ce7a2a82022572f4d
Parents: b46bd22
Author: Guillaume Nodet <gn...@gmail.com>
Authored: Mon May 19 09:59:53 2014 +0200
Committer: Guillaume Nodet <gn...@gmail.com>
Committed: Mon May 19 21:16:05 2014 +0200
----------------------------------------------------------------------
assemblies/features/standard/src/main/feature/feature.xml | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/0cf070d4/assemblies/features/standard/src/main/feature/feature.xml
----------------------------------------------------------------------
diff --git a/assemblies/features/standard/src/main/feature/feature.xml b/assemblies/features/standard/src/main/feature/feature.xml
index a7f6e60..c02dea0 100644
--- a/assemblies/features/standard/src/main/feature/feature.xml
+++ b/assemblies/features/standard/src/main/feature/feature.xml
@@ -273,7 +273,7 @@
<feature name="scr" description="Declarative Service support" version="${project.version}">
<feature>eventadmin</feature>
<bundle dependency="true" start-level="30">mvn:org.apache.felix/org.apache.felix.metatype/${felix.metatype.version}</bundle>
- <bundle dependency="true" start-level="30">mvn:org.apache.felix/org.apache.felix.scr/${felix.scr.version}</bundle>
+ <bundle start-level="30">mvn:org.apache.felix/org.apache.felix.scr/${felix.scr.version}</bundle>
<bundle start-level="30">mvn:org.apache.karaf.scr/org.apache.karaf.scr.command/${project.version}</bundle>
<conditional>
<condition>management</condition>
@@ -283,6 +283,10 @@
<condition>webconsole</condition>
<bundle start-level="30">mvn:org.apache.felix/org.apache.felix.webconsole.plugins.ds/${felix.scr.webconsole.plugin.version}</bundle>
</conditional>
+ <capability>
+ osgi.service;effective:=active;objectClass=org.apache.felix.scr.ScrService,
+ osgi.extender;osgi.extender="osgi.component";uses:="org.osgi.service.component";version:Version="1.2.1"
+ </capability>
</feature>
<feature name="blueprint-web" description="Provides an OSGI-aware Servlet ContextListener for bootstrapping