You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by jw...@apache.org on 2012/03/14 19:47:59 UTC
svn commit: r1300686 - in /aries/trunk/subsystem:
subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/
subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/
subsystem-core/src/main/java/org/apache/aries/subsystem/core/...
Author: jwross
Date: Wed Mar 14 18:47:59 2012
New Revision: 1300686
URL: http://svn.apache.org/viewvc?rev=1300686&view=rev
Log:
ARIES-825: Update subsystems to latest Subsystem, Resolver, and Repository APIs.
Added initial support for provision-policy directive on Subsystem-Type header.
Added:
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ProvisionPolicyDirective.java
aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/ProvisionPolicyTest.java
Modified:
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleManifest.java
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleVersionHeader.java
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/DeploymentManifest.java
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/DirectiveFactory.java
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemContentHeader.java
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemManifest.java
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemTypeHeader.java
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/AriesSubsystem.java
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/OsgiIdentityCapability.java
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemManifestValidator.java
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemDirectoryResource.java
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemStreamResource.java
aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/ApplicationTest.java
aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/IntegrationTest.java
aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleManifest.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleManifest.java?rev=1300686&r1=1300685&r2=1300686&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleManifest.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleManifest.java Wed Mar 14 18:47:59 2012
@@ -13,8 +13,17 @@
*/
package org.apache.aries.subsystem.core.archive;
+import org.osgi.framework.Constants;
+
public class BundleManifest extends Manifest {
public BundleManifest(java.util.jar.Manifest manifest) {
super(manifest);
+ fillInDefaults();
+ }
+
+ private void fillInDefaults() {
+ Header<?> header = headers.get(Constants.BUNDLE_VERSION);
+ if (header == null)
+ headers.put(Constants.BUNDLE_VERSION, BundleVersionHeader.DEFAULT);
}
}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleVersionHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleVersionHeader.java?rev=1300686&r1=1300685&r2=1300686&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleVersionHeader.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleVersionHeader.java Wed Mar 14 18:47:59 2012
@@ -7,6 +7,8 @@ public class BundleVersionHeader extends
public static final String DEFAULT_VALUE = Version.emptyVersion.toString();
public static final String NAME = Constants.BUNDLE_VERSION;
+ public static final BundleVersionHeader DEFAULT = new BundleVersionHeader();
+
public BundleVersionHeader() {
this(DEFAULT_VALUE);
}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/DeploymentManifest.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/DeploymentManifest.java?rev=1300686&r1=1300685&r2=1300686&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/DeploymentManifest.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/DeploymentManifest.java Wed Mar 14 18:47:59 2012
@@ -112,7 +112,7 @@ public class DeploymentManifest {
headers.put(SUBSYSTEM_SYMBOLICNAME, subsystemManifest.getSubsystemSymbolicNameHeader());
headers.put(SUBSYSTEM_VERSION, subsystemManifest.getSubsystemVersionHeader());
SubsystemTypeHeader typeHeader = subsystemManifest.getSubsystemTypeHeader();
- if (SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION.equals(typeHeader.getValue())) {
+ if (typeHeader.isApplication()) {
if (resolution != null) {
Header<?> header = computeImportPackageHeader(resolution, deployedContent, acceptDependencies);
if (header != null)
@@ -126,7 +126,7 @@ public class DeploymentManifest {
}
// TODO Compute additional headers for an application.
}
- else if (SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE.equals(typeHeader.getValue())) {
+ else if (typeHeader.isComposite()) {
Header<?> header = subsystemManifest.getImportPackageHeader();
if (header != null)
headers.put(IMPORT_PACKAGE, header);
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/DirectiveFactory.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/DirectiveFactory.java?rev=1300686&r1=1300685&r2=1300686&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/DirectiveFactory.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/DirectiveFactory.java Wed Mar 14 18:47:59 2012
@@ -25,6 +25,8 @@ public class DirectiveFactory {
return EffectiveDirective.getInstance(value);
if (VisibilityDirective.NAME.equals(name))
return VisibilityDirective.getInstance(value);
+ if (ProvisionPolicyDirective.NAME.equals(name))
+ return ProvisionPolicyDirective.getInstance(value);
return new GenericDirective(name, value);
}
}
Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ProvisionPolicyDirective.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ProvisionPolicyDirective.java?rev=1300686&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ProvisionPolicyDirective.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ProvisionPolicyDirective.java Wed Mar 14 18:47:59 2012
@@ -0,0 +1,42 @@
+package org.apache.aries.subsystem.core.archive;
+
+import org.osgi.service.subsystem.SubsystemConstants;
+
+public class ProvisionPolicyDirective extends AbstractDirective {
+ public static final String NAME = SubsystemConstants.PROVISION_POLICY_DIRECTIVE;
+ public static final String VALUE_ACCEPT_DEPENDENCIES = SubsystemConstants.PROVISION_POLICY_ACCEPT_DEPENDENCIES;
+ public static final String VALUE_REJECT_DEPENDENCIES = SubsystemConstants.PROVISION_POLICY_REJECT_DEPENDENCIES;
+
+ public static final ProvisionPolicyDirective ACCEPT_DEPENDENCIES = new ProvisionPolicyDirective(VALUE_ACCEPT_DEPENDENCIES);
+ public static final ProvisionPolicyDirective REJECT_DEPENDENCIES = new ProvisionPolicyDirective(VALUE_REJECT_DEPENDENCIES);
+
+ public static final ProvisionPolicyDirective DEFAULT = REJECT_DEPENDENCIES;
+
+ public static ProvisionPolicyDirective getInstance(String value) {
+ if (VALUE_ACCEPT_DEPENDENCIES.equals(value))
+ return ACCEPT_DEPENDENCIES;
+ if (VALUE_REJECT_DEPENDENCIES.equals(value))
+ return REJECT_DEPENDENCIES;
+ return new ProvisionPolicyDirective(value);
+ }
+
+ public ProvisionPolicyDirective(String value) {
+ super(NAME, value);
+ if (!(VALUE_ACCEPT_DEPENDENCIES.equals(value)
+ || VALUE_REJECT_DEPENDENCIES.equals(value))) {
+ throw new IllegalArgumentException("Invalid " + NAME + " directive value: " + value);
+ }
+ }
+
+ public String getProvisionPolicy() {
+ return getValue();
+ }
+
+ public boolean isAcceptDependencies() {
+ return this == ACCEPT_DEPENDENCIES || VALUE_ACCEPT_DEPENDENCIES.equals(getProvisionPolicy());
+ }
+
+ public boolean isRejectDependencies() {
+ return this == REJECT_DEPENDENCIES || VALUE_REJECT_DEPENDENCIES.equals(getProvisionPolicy());
+ }
+}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemContentHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemContentHeader.java?rev=1300686&r1=1300685&r2=1300686&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemContentHeader.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemContentHeader.java Wed Mar 14 18:47:59 2012
@@ -18,12 +18,16 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
+import java.util.Map;
import org.apache.aries.subsystem.core.ResourceHelper;
import org.osgi.framework.Constants;
import org.osgi.framework.Version;
import org.osgi.framework.VersionRange;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.resource.Capability;
import org.osgi.resource.Resource;
+import org.osgi.service.subsystem.SubsystemConstants;
public class SubsystemContentHeader extends AbstractHeader {
public static class Content {
@@ -83,8 +87,26 @@ public class SubsystemContentHeader exte
}
}
- // TODO Add to constants.
- public static final String NAME = "Subsystem-Content";
+ public static final String NAME = SubsystemConstants.SUBSYSTEM_CONTENT;
+
+ private static String processResources(Collection<Resource> resources) {
+ if (resources.isEmpty())
+ throw new IllegalArgumentException("At least one resource must be specified");
+ StringBuilder sb = new StringBuilder();
+ for (Resource resource : resources) {
+ Capability c = resource.getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE).get(0);
+ Map<String, Object> a = c.getAttributes();
+ String s = (String)a.get(IdentityNamespace.IDENTITY_NAMESPACE);
+ Version v = (Version)a.get(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE);
+ String t = (String)a.get(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE);
+ sb.append(s).append(';')
+ .append(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE).append('=').append(v).append(';')
+ .append(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE).append('=').append(t).append(',');
+ }
+ // Remove the trailing comma.
+ sb.deleteCharAt(sb.length() - 1);
+ return sb.toString();
+ }
private final List<Content> contents;
@@ -121,6 +143,10 @@ public class SubsystemContentHeader exte
});
}
+ public SubsystemContentHeader(Collection<Resource> resources) {
+ this(processResources(resources));
+ }
+
public boolean contains(Resource resource) {
String symbolicName = ResourceHelper.getSymbolicNameAttribute(resource);
Version version = ResourceHelper.getVersionAttribute(resource);
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemManifest.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemManifest.java?rev=1300686&r1=1300685&r2=1300686&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemManifest.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemManifest.java Wed Mar 14 18:47:59 2012
@@ -16,12 +16,60 @@ import java.util.jar.Manifest;
import org.apache.aries.util.manifest.ManifestProcessor;
import org.osgi.framework.Constants;
import org.osgi.framework.Version;
-import org.osgi.framework.namespace.IdentityNamespace;
-import org.osgi.resource.Capability;
import org.osgi.resource.Resource;
import org.osgi.service.subsystem.SubsystemConstants;
public class SubsystemManifest {
+ public static class Builder {
+ private Map<String, Header<?>> headers = new HashMap<String, Header<?>>();
+
+ public Builder(String symbolicName) {
+ headers.put(SUBSYSTEM_SYMBOLICNAME, new SubsystemSymbolicNameHeader(symbolicName));
+ }
+
+ public SubsystemManifest build() {
+ return new SubsystemManifest(headers);
+ }
+
+ public Builder content(String value) {
+ return value == null ? this : content(new SubsystemContentHeader(value));
+ }
+
+ public Builder content(Collection<Resource> value) {
+ return value == null || value.isEmpty() ? this : content(new SubsystemContentHeader(value));
+ }
+
+ public Builder content(SubsystemContentHeader value) {
+ return header(value);
+ }
+
+ public Builder header(Header<?> value) {
+ if (value != null)
+ headers.put(value.getName(), value);
+ return this;
+ }
+
+ public Builder type(String value) {
+ return value == null ? this : type(new SubsystemTypeHeader(value));
+ }
+
+ public Builder type(SubsystemTypeHeader value) {
+ return header(value);
+ }
+
+ public Builder version(String value) {
+ return value == null ? this : version(Version.parseVersion(value));
+ }
+
+ public Builder version(Version value) {
+ return value == null ? this : version(new SubsystemVersionHeader(value));
+ }
+
+ public Builder version(SubsystemVersionHeader value) {
+ return header(value);
+ }
+ }
+
public static final String EXPORT_PACKAGE = Constants.EXPORT_PACKAGE;
public static final String IMPORT_PACKAGE = Constants.IMPORT_PACKAGE;
public static final String PREFERRED_PROVIDER = SubsystemConstants.PREFERRED_PROVIDER;
@@ -38,8 +86,24 @@ public class SubsystemManifest {
public static final String SUBSYSTEM_TYPE = SubsystemConstants.SUBSYSTEM_TYPE;
public static final String SUBSYSTEM_VERSION = SubsystemConstants.SUBSYSTEM_VERSION;
+ private static void fillInDefaults(Map<String, Header<?>> headers) {
+ Header<?> header = headers.get(SUBSYSTEM_VERSION);
+ if (header == null) {
+ headers.put(SUBSYSTEM_VERSION, SubsystemVersionHeader.DEFAULT);
+ }
+ header = headers.get(SUBSYSTEM_TYPE);
+ if (header == null)
+ headers.put(SUBSYSTEM_TYPE, SubsystemTypeHeader.DEFAULT);
+ }
+
private final Map<String, Header<?>> headers;
+ private SubsystemManifest(Map<String, Header<?>> headers) {
+ Map<String, Header<?>> map = new HashMap<String, Header<?>>(headers);
+ fillInDefaults(map);
+ this.headers = Collections.unmodifiableMap(map);
+ }
+
public SubsystemManifest(File file) throws FileNotFoundException, IOException {
Manifest manifest = ManifestProcessor.parseManifest(new FileInputStream(file));
Attributes attributes = manifest.getMainAttributes();
@@ -48,13 +112,7 @@ public class SubsystemManifest {
String key = String.valueOf(entry.getKey());
headers.put(key, HeaderFactory.createHeader(key, String.valueOf(entry.getValue())));
}
- Header<?> header = headers.get(SUBSYSTEM_VERSION);
- if (header == null) {
- headers.put(SUBSYSTEM_VERSION, SubsystemVersionHeader.DEFAULT);
- }
- header = headers.get(SUBSYSTEM_TYPE);
- if (header == null)
- headers.put(SUBSYSTEM_TYPE, SubsystemTypeHeader.DEFAULT);
+ fillInDefaults(headers);
this.headers = Collections.unmodifiableMap(headers);
}
@@ -74,35 +132,14 @@ public class SubsystemManifest {
if (header == null)
headers.put(SUBSYSTEM_SYMBOLICNAME, new SubsystemSymbolicNameHeader(symbolicName));
header = headers.get(SUBSYSTEM_VERSION);
- if (header == null) {
- if (version == null)
- headers.put(SUBSYSTEM_VERSION, SubsystemVersionHeader.DEFAULT);
- else
- headers.put(SUBSYSTEM_VERSION, new SubsystemVersionHeader(version));
+ if (header == null && !(version == null)) {
+ headers.put(SUBSYSTEM_VERSION, new SubsystemVersionHeader(version));
}
header = headers.get(SUBSYSTEM_CONTENT);
if (header == null && content != null && !content.isEmpty()) {
- // TODO Better way than using StringBuilder? Would require a more robust SubsystemContentHeader in order to fulfill the Header contract.
- StringBuilder sb = new StringBuilder();
- for (Resource resource : content) {
- Capability c = resource.getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE).get(0);
- Map<String, Object> a = c.getAttributes();
- String s = (String)a.get(IdentityNamespace.IDENTITY_NAMESPACE);
- Version v = (Version)a.get(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE);
- String t = (String)a.get(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE);
- sb.append(s).append(';')
- .append(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE).append('=').append(v).append(';')
- .append(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE).append('=').append(t).append(',');
- }
- if (sb.length() != 0) {
- // Remove the trailing comma.
- sb.deleteCharAt(sb.length() - 1);
- headers.put(SubsystemContentHeader.NAME, new SubsystemContentHeader(sb.toString()));
- }
+ headers.put(SubsystemContentHeader.NAME, new SubsystemContentHeader(content));
}
- header = headers.get(SUBSYSTEM_TYPE);
- if (header == null)
- headers.put(SUBSYSTEM_TYPE, SubsystemTypeHeader.DEFAULT);
+ fillInDefaults(headers);
this.headers = Collections.unmodifiableMap(headers);
}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemTypeHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemTypeHeader.java?rev=1300686&r1=1300685&r2=1300686&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemTypeHeader.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemTypeHeader.java Wed Mar 14 18:47:59 2012
@@ -13,18 +13,193 @@
*/
package org.apache.aries.subsystem.core.archive;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
import org.osgi.service.subsystem.SubsystemConstants;
-public class SubsystemTypeHeader extends AbstractHeader {
- public static final SubsystemTypeHeader DEFAULT = new SubsystemTypeHeader();
- public static final String DEFAULT_VALUE = SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION;
+public class SubsystemTypeHeader implements Header<SubsystemTypeHeader.Clause> {
+ public static class Clause implements org.apache.aries.subsystem.core.archive.Clause {
+ private static final Pattern PATTERN_TYPE = Pattern.compile('(' + TYPE_APPLICATION + '|' + TYPE_COMPOSITE + '|' + TYPE_FEATURE + ")(?=;|\\z)");
+ private static final Pattern PATTERN_PARAMETER = Pattern.compile('(' + Grammar.PARAMETER + ")(?=;|\\z)");
+ private static final Pattern PATTERN_PROVISION_POLICY = Pattern.compile(PROVISION_POLICY_ACCEPT_DEPENDENCIES + '|' + PROVISION_POLICY_REJECT_DEPENDENCIES);
+
+ private static void fillInDefaults(Map<String, Parameter> parameters) {
+ Parameter parameter = parameters.get(DIRECTIVE_PROVISION_POLICY);
+ if (parameter == null)
+ parameter = ProvisionPolicyDirective.REJECT_DEPENDENCIES;
+ String value = ((Directive)parameter).getValue();
+ if (!PATTERN_PROVISION_POLICY.matcher(value).matches())
+ throw new IllegalArgumentException("Invalid " + DIRECTIVE_PROVISION_POLICY + " directive: " + value);
+ parameters.put(DIRECTIVE_PROVISION_POLICY, parameter);
+ }
+
+ private final String path;
+ private final Map<String, Parameter> parameters = new HashMap<String, Parameter>();
+
+ public Clause(String clause) {
+ Matcher matcher = PATTERN_TYPE.matcher(clause);
+ if (!matcher.find())
+ throw new IllegalArgumentException("Invalid subsystem type: " + clause);
+ path = matcher.group();
+ matcher.usePattern(PATTERN_PARAMETER);
+ while (matcher.find()) {
+ Parameter parameter = ParameterFactory.create(matcher.group());
+ parameters.put(parameter.getName(), parameter);
+ }
+ fillInDefaults(parameters);
+ }
+
+ @Override
+ public Attribute getAttribute(String name) {
+ Parameter result = parameters.get(name);
+ if (result instanceof Attribute) {
+ return (Attribute)result;
+ }
+ return null;
+ }
+
+ @Override
+ public Collection<Attribute> getAttributes() {
+ ArrayList<Attribute> attributes = new ArrayList<Attribute>(parameters.size());
+ for (Parameter parameter : parameters.values()) {
+ if (parameter instanceof Attribute) {
+ attributes.add((Attribute)parameter);
+ }
+ }
+ attributes.trimToSize();
+ return attributes;
+ }
+
+ @Override
+ public Directive getDirective(String name) {
+ Parameter result = parameters.get(name);
+ if (result instanceof Directive) {
+ return (Directive)result;
+ }
+ return null;
+ }
+
+ @Override
+ public Collection<Directive> getDirectives() {
+ ArrayList<Directive> directives = new ArrayList<Directive>(parameters.size());
+ for (Parameter parameter : parameters.values()) {
+ if (parameter instanceof Directive) {
+ directives.add((Directive)parameter);
+ }
+ }
+ directives.trimToSize();
+ return directives;
+ }
+
+ @Override
+ public Parameter getParameter(String name) {
+ return parameters.get(name);
+ }
+
+ @Override
+ public Collection<Parameter> getParameters() {
+ return Collections.unmodifiableCollection(parameters.values());
+ }
+
+ @Override
+ public String getPath() {
+ return path;
+ }
+
+ public ProvisionPolicyDirective getProvisionPolicyDirective() {
+ return (ProvisionPolicyDirective)getDirective(DIRECTIVE_PROVISION_POLICY);
+ }
+
+ public String getType() {
+ return path;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder()
+ .append(getPath());
+ for (Parameter parameter : getParameters()) {
+ builder.append(';').append(parameter);
+ }
+ return builder.toString();
+ }
+ }
+
+ public static final String DIRECTIVE_PROVISION_POLICY = SubsystemConstants.PROVISION_POLICY_DIRECTIVE;
public static final String NAME = SubsystemConstants.SUBSYSTEM_TYPE;
+ public static final String PROVISION_POLICY_ACCEPT_DEPENDENCIES = SubsystemConstants.PROVISION_POLICY_ACCEPT_DEPENDENCIES;
+ public static final String PROVISION_POLICY_REJECT_DEPENDENCIES = SubsystemConstants.PROVISION_POLICY_REJECT_DEPENDENCIES;
+ public static final String TYPE_APPLICATION = SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION;
+ public static final String TYPE_COMPOSITE = SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE;
+ public static final String TYPE_FEATURE = SubsystemConstants.SUBSYSTEM_TYPE_FEATURE;
- public SubsystemTypeHeader() {
- this(DEFAULT_VALUE);
+ public static final SubsystemTypeHeader DEFAULT = new SubsystemTypeHeader(TYPE_APPLICATION);
+
+ private final Clause clause;
+
+ public SubsystemTypeHeader(Clause clause) {
+ if (clause == null)
+ throw new NullPointerException("Missing required parameter: clause");
+ this.clause = clause;
}
-
+
public SubsystemTypeHeader(String value) {
- super(NAME, value);
+ this(new Clause(value));
+ }
+
+ public Clause getClause() {
+ return clause;
+ }
+
+ @Override
+ public Collection<SubsystemTypeHeader.Clause> getClauses() {
+ return Collections.singleton(clause);
+ }
+
+ @Override
+ public String getName() {
+ return NAME;
+ }
+
+ public ProvisionPolicyDirective getProvisionPolicyDirective() {
+ return clause.getProvisionPolicyDirective();
+ }
+
+ public String getType() {
+ return clause.getType();
+ }
+
+ @Override
+ public String getValue() {
+ return toString();
+ }
+
+ public boolean isApplication() {
+ return this == DEFAULT || TYPE_APPLICATION.equals(getType());
+ }
+
+ public boolean isComposite() {
+ return TYPE_COMPOSITE.equals(getType());
+ }
+
+ public boolean isFeature() {
+ return TYPE_FEATURE.equals(getType());
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ for (Clause clause : getClauses()) {
+ builder.append(clause).append(',');
+ }
+ // Remove the trailing comma. Note at least one clause is guaranteed to exist.
+ builder.deleteCharAt(builder.length() - 1);
+ return builder.toString();
}
}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/AriesSubsystem.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/AriesSubsystem.java?rev=1300686&r1=1300685&r2=1300686&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/AriesSubsystem.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/AriesSubsystem.java Wed Mar 14 18:47:59 2012
@@ -65,6 +65,7 @@ import org.apache.aries.subsystem.core.a
import org.apache.aries.subsystem.core.archive.SubsystemImportServiceHeader;
import org.apache.aries.subsystem.core.archive.SubsystemImportServiceRequirement;
import org.apache.aries.subsystem.core.archive.SubsystemManifest;
+import org.apache.aries.subsystem.core.archive.SubsystemTypeHeader;
import org.apache.aries.subsystem.core.resource.SubsystemDirectoryResource;
import org.apache.aries.subsystem.core.resource.SubsystemFileResource;
import org.apache.aries.subsystem.core.resource.SubsystemStreamResource;
@@ -272,16 +273,28 @@ public class AriesSubsystem implements S
// TODO The creation of the subsystem manifest is in two places. See other constructor.
SubsystemManifest subsystemManifest = archive.getSubsystemManifest();
if (subsystemManifest == null) {
- // This is the first time the root subsystem has been initialized in this framework or
- // a framework clean start was requested.
+ // This is the first time the root subsystem has been initialized in
+ // this framework or a framework clean start was requested.
SubsystemUri uri = new SubsystemUri(ROOT_LOCATION);
- subsystemManifest = new SubsystemManifest(uri.getSymbolicName(), uri.getVersion(), archive.getResources());
+ subsystemManifest = new SubsystemManifest.Builder(
+ uri.getSymbolicName())
+ .version(uri.getVersion())
+ .content(archive.getResources())
+ .type(SubsystemTypeHeader.TYPE_APPLICATION
+ + ';'
+ + SubsystemTypeHeader.DIRECTIVE_PROVISION_POLICY
+ + ":="
+ + SubsystemTypeHeader.PROVISION_POLICY_ACCEPT_DEPENDENCIES)
+ .build();
archive.setSubsystemManifest(subsystemManifest);
}
- else
+ else {
// Need to generate a new subsystem manifest in order to generated a new deployment manifest based
// on any persisted resources.
- subsystemManifest = new SubsystemManifest(getSymbolicName(), getVersion(), archive.getResources());
+ subsystemManifest = new SubsystemManifest.Builder(getSymbolicName())
+ .version(getVersion()).content(archive.getResources())
+ .build();
+ }
environment = new SubsystemEnvironment(this);
// The root subsystem establishes the subsystem graph;
subsystemGraph = new SubsystemGraph(this);
@@ -349,10 +362,12 @@ public class AriesSubsystem implements S
else
region = createRegion(getSymbolicName() + ';' + getVersion() + ';' + getType() + ';' + getSubsystemId());
}
- catch (Exception e) {
+ catch (Throwable t) {
deleteFile(directory);
deleteFile(zipFile);
- throw new SubsystemException(e);
+ if (t instanceof SubsystemException)
+ throw (SubsystemException)t;
+ throw new SubsystemException(t);
}
subsystemGraph = parent.subsystemGraph;
}
@@ -461,7 +476,7 @@ public class AriesSubsystem implements S
@Override
public String getType() {
- return archive.getSubsystemManifest().getSubsystemTypeHeader().getValue();
+ return archive.getSubsystemManifest().getSubsystemTypeHeader().getType();
}
@Override
@@ -481,36 +496,33 @@ public class AriesSubsystem implements S
try {
result = install(location, content, coordination);
}
- catch (Exception e) {
- coordination.fail(e);
+ catch (Throwable t) {
+ coordination.fail(t);
}
finally {
try {
coordination.end();
}
catch (CoordinationException e) {
- throw new SubsystemException(e);
+ Throwable t = e.getCause();
+ if (t instanceof SubsystemException)
+ throw (SubsystemException)t;
+ throw new SubsystemException(t);
}
}
return result;
}
public boolean isApplication() {
- return SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION.equals(archive
- .getSubsystemManifest().getHeaders()
- .get(SubsystemManifest.SUBSYSTEM_TYPE).getValue());
+ return archive.getSubsystemManifest().getSubsystemTypeHeader().isApplication();
}
public boolean isComposite() {
- return SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE.equals(archive
- .getSubsystemManifest().getHeaders()
- .get(SubsystemManifest.SUBSYSTEM_TYPE).getValue());
+ return archive.getSubsystemManifest().getSubsystemTypeHeader().isComposite();
}
public boolean isFeature() {
- return SubsystemConstants.SUBSYSTEM_TYPE_FEATURE.equals(archive
- .getSubsystemManifest().getHeaders()
- .get(SubsystemManifest.SUBSYSTEM_TYPE).getValue());
+ return archive.getSubsystemManifest().getSubsystemTypeHeader().isFeature();
}
/* INSTALLING Wait, Start
@@ -778,12 +790,13 @@ public class AriesSubsystem implements S
}
private AriesSubsystem getProvisionTo(Resource resource, boolean transitive) {
- // Application and composite resources are provisioned into the application or composite.
+ // Content resources are provisioned into the subsystem that declares
+ // them.
AriesSubsystem provisionTo = this;
if (transitive) {
- // Transitive dependencies should be provisioned into the highest possible level.
- // TODO Assumes root is always the appropriate level.
- while (!provisionTo.getParents().isEmpty())
+ // Transitive dependencies should be provisioned into the first
+ // subsystem that accepts dependencies.
+ while (provisionTo.archive.getSubsystemManifest().getSubsystemTypeHeader().getProvisionPolicyDirective().isRejectDependencies())
provisionTo = (AriesSubsystem)provisionTo.getParents().iterator().next();
}
return provisionTo;
@@ -883,6 +896,9 @@ public class AriesSubsystem implements S
installSubsystemResource(subsystem, coordination, false);
return subsystem;
}
+ catch (SubsystemException e) {
+ throw e;
+ }
catch (Exception e) {
throw new SubsystemException(e);
}
@@ -897,10 +913,10 @@ public class AriesSubsystem implements S
final BundleRevision revision;
AriesSubsystem provisionTo = getProvisionTo(resource, transitive);
if (resource instanceof BundleRevision) {
- // This means the resource is a bundle that's already been installed, but we still need to establish the resource->subsystem relationship.
+ // This means the resource is an already installed bundle.
revision = (BundleRevision)resource;
// Need to simulate the install process since an install does not
- // actually occur here and the event hook is not called.
+ // actually occur here, and the event hook is not called.
provisionTo.bundleInstalled(revision);
}
else {
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/OsgiIdentityCapability.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/OsgiIdentityCapability.java?rev=1300686&r1=1300685&r2=1300686&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/OsgiIdentityCapability.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/OsgiIdentityCapability.java Wed Mar 14 18:47:59 2012
@@ -56,7 +56,7 @@ public class OsgiIdentityCapability exte
resource,
manifest.getSubsystemSymbolicNameHeader().getSymbolicName(),
manifest.getSubsystemVersionHeader().getVersion(),
- manifest.getSubsystemTypeHeader().getValue());
+ manifest.getSubsystemTypeHeader().getType());
}
public OsgiIdentityCapability(Resource resource, BundleManifest manifest) {
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemManifestValidator.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemManifestValidator.java?rev=1300686&r1=1300685&r2=1300686&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemManifestValidator.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemManifestValidator.java Wed Mar 14 18:47:59 2012
@@ -17,6 +17,11 @@ public class SubsystemManifestValidator
throw new SubsystemException("Composite subsystem using version range for content: " + content);
}
}
+ else if (subsystem.isFeature()) {
+ if (manifest.getSubsystemTypeHeader().getProvisionPolicyDirective().isAcceptDependencies()) {
+ throw new SubsystemException("Feature subsystems may not declare a provision-policy of acceptDependencies");
+ }
+ }
}
private static boolean isExactVersion(VersionRange range) {
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemDirectoryResource.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemDirectoryResource.java?rev=1300686&r1=1300685&r2=1300686&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemDirectoryResource.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemDirectoryResource.java Wed Mar 14 18:47:59 2012
@@ -25,7 +25,7 @@ public class SubsystemDirectoryResource
this,
manifest.getSubsystemSymbolicNameHeader().getSymbolicName(),
manifest.getSubsystemVersionHeader().getVersion(),
- manifest.getSubsystemTypeHeader().getValue()));
+ manifest.getSubsystemTypeHeader().getType()));
this.capabilities = Collections.unmodifiableList(capabilities);
}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemStreamResource.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemStreamResource.java?rev=1300686&r1=1300685&r2=1300686&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemStreamResource.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemStreamResource.java Wed Mar 14 18:47:59 2012
@@ -70,7 +70,7 @@ public class SubsystemStreamResource imp
version = Version.parseVersion(value);
value = manifest.getMainAttributes().getValue(SubsystemConstants.SUBSYSTEM_TYPE);
if (value != null)
- type = new SubsystemTypeHeader(value).getValue();
+ type = new SubsystemTypeHeader(value).getType();
}
if (symbolicName == null) {
if (uri == null)
Modified: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/ApplicationTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/ApplicationTest.java?rev=1300686&r1=1300685&r2=1300686&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/ApplicationTest.java (original)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/ApplicationTest.java Wed Mar 14 18:47:59 2012
@@ -167,7 +167,7 @@ public class ApplicationTest extends Sub
createdApplications = true;
}
- public void setUp() {
+ public void setUp() throws Exception {
super.setUp();
try {
serviceRegistrations.add(
@@ -266,7 +266,7 @@ public class ApplicationTest extends Sub
.namespace(PackageNamespace.PACKAGE_NAMESPACE)
.attribute(PackageNamespace.PACKAGE_NAMESPACE, "org.apache.aries.subsystem.itests.tb3")
.attribute(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE, "0.0.0"))
- .content(createTestBundle3Content())
+ .content(createTestBundle3Content())
.build();
}
Modified: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/IntegrationTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/IntegrationTest.java?rev=1300686&r1=1300685&r2=1300686&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/IntegrationTest.java (original)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/IntegrationTest.java Wed Mar 14 18:47:59 2012
@@ -53,7 +53,7 @@ public abstract class IntegrationTest {
private Map<String, ServiceTracker> srs;
@Before
- public void setUp() {
+ public void setUp() throws Exception {
srs = new HashMap<String, ServiceTracker>();
}
Added: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/ProvisionPolicyTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/ProvisionPolicyTest.java?rev=1300686&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/ProvisionPolicyTest.java (added)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/ProvisionPolicyTest.java Wed Mar 14 18:47:59 2012
@@ -0,0 +1,241 @@
+package org.apache.aries.subsystem.itests;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.osgi.framework.Constants;
+import org.osgi.service.subsystem.Subsystem;
+import org.osgi.service.subsystem.SubsystemConstants;
+import org.osgi.service.subsystem.SubsystemException;
+
+@RunWith(JUnit4TestRunner.class)
+public class ProvisionPolicyTest extends SubsystemTest {
+ /*
+ * Subsystem-SymbolicName: application.a.esa
+ * Subsystem-Type: osgi.subsystem.application;provision-policy:=acceptDependencies
+ */
+ private static final String APPLICATION_A = "application.a.esa";
+ /*
+ * Bundle-SymbolicName: bundle.a.jar
+ * Import-Package: x
+ */
+ private static final String BUNDLE_A = "bundle.a.jar";
+ /*
+ * Bundle-SymbolicName: bundle.b.jar
+ * Export-Package: x
+ */
+ private static final String BUNDLE_B = "bundle.b.jar";
+ /*
+ * Subsystem-SymbolicName: composite.a.esa
+ * Subsystem-Type: osgi.subsystem.composite
+ * Import-Package: x
+ */
+ private static final String COMPOSITE_A = "composite.a.esa";
+ /*
+ * Subsystem-SymbolicName: feature.a.esa
+ * Subsystem-Type: osgi.subsystem.feature;provision-policy:=acceptDependencies
+ */
+ private static final String FEATURE_A = "feature.a.esa";
+ /*
+ * Subsystem-SymbolicName: feature.b.esa
+ * Subsystem-Type: osgi.subsystem.feature
+ * Subsystem-Content: bundle.a.jar
+ */
+ private static final String FEATURE_B = "feature.b.esa";
+
+ private static void createApplicationA() throws IOException {
+ createApplicationAManifest();
+ createSubsystem(APPLICATION_A, BUNDLE_A);
+ }
+
+ private static void createApplicationAManifest() throws IOException {
+ Map<String, String> attributes = new HashMap<String, String>();
+ attributes.put(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME, APPLICATION_A);
+ attributes
+ .put(SubsystemConstants.SUBSYSTEM_TYPE,
+ SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION
+ + ';'
+ + SubsystemConstants.PROVISION_POLICY_DIRECTIVE
+ + ":="
+ + SubsystemConstants.PROVISION_POLICY_ACCEPT_DEPENDENCIES);
+ createManifest(APPLICATION_A + ".mf", attributes);
+ }
+
+ private static void createBundleA() throws IOException {
+ Map<String, String> headers = new HashMap<String, String>();
+ headers.put(Constants.IMPORT_PACKAGE, "x");
+ createBundle(BUNDLE_A, headers);
+ }
+
+ private static void createBundleB() throws IOException {
+ Map<String, String> headers = new HashMap<String, String>();
+ headers.put(Constants.EXPORT_PACKAGE, "x");
+ createBundle(BUNDLE_B, headers);
+ }
+
+ private static void createCompositeA() throws IOException {
+ createCompositeAManifest();
+ createSubsystem(COMPOSITE_A);
+ }
+
+ private static void createCompositeAManifest() throws IOException {
+ Map<String, String> attributes = new HashMap<String, String>();
+ attributes.put(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME, COMPOSITE_A);
+ attributes.put(SubsystemConstants.SUBSYSTEM_TYPE, SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE);
+ attributes.put(Constants.IMPORT_PACKAGE, "x");
+ createManifest(COMPOSITE_A + ".mf", attributes);
+ }
+
+ private static void createFeatureA() throws IOException {
+ createFeatureAManifest();
+ createSubsystem(FEATURE_A);
+ }
+
+ private static void createFeatureAManifest() throws IOException {
+ Map<String, String> attributes = new HashMap<String, String>();
+ attributes.put(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME, FEATURE_A);
+ attributes
+ .put(SubsystemConstants.SUBSYSTEM_TYPE,
+ SubsystemConstants.SUBSYSTEM_TYPE_FEATURE
+ + ';'
+ + SubsystemConstants.PROVISION_POLICY_DIRECTIVE
+ + ":="
+ + SubsystemConstants.PROVISION_POLICY_ACCEPT_DEPENDENCIES);
+ createManifest(FEATURE_A + ".mf", attributes);
+ }
+
+ private static void createFeatureB() throws IOException {
+ createFeatureBManifest();
+ createSubsystem(FEATURE_B, BUNDLE_A);
+ }
+
+ private static void createFeatureBManifest() throws IOException {
+ Map<String, String> attributes = new HashMap<String, String>();
+ attributes.put(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME, FEATURE_B);
+ attributes.put(SubsystemConstants.SUBSYSTEM_TYPE, SubsystemConstants.SUBSYSTEM_TYPE_FEATURE);
+ attributes.put(SubsystemConstants.SUBSYSTEM_CONTENT, BUNDLE_A);
+ createManifest(FEATURE_B + ".mf", attributes);
+ }
+
+ private static boolean createdTestFiles;
+ @Before
+ public static void createTestFiles() throws Exception {
+ if (createdTestFiles)
+ return;
+ createBundleA();
+ createBundleB();
+ createApplicationA();
+ createCompositeA();
+ createFeatureA();
+ createFeatureB();
+ createdTestFiles = true;
+ }
+
+ public void setUp() throws Exception {
+ super.setUp();
+ Subsystem root = getRootSubsystem();
+ assertProvisionPolicy(root, true);
+ registerRepositoryService(BUNDLE_B);
+ }
+
+ @Test
+ public void testFailInstallFeatureAcceptDependencies() throws Exception {
+ Subsystem subsystem = null;
+ try {
+ subsystem = installSubsystemFromFile(FEATURE_A);
+ fail("Feature with provision-policy:=acceptDependencies did not fail installation");
+ }
+ catch (SubsystemException e) {
+ // TODO Brittle...
+ assertTrue(e.getMessage().contains("Feature subsystems may not declare a provision-policy of acceptDependencies"));
+ }
+ finally {
+ uninstallSubsystemSilently(subsystem);
+ }
+ }
+
+ @Test
+ public void testProvisionToNonRootAncestor() throws Exception {
+ Subsystem root = getRootSubsystem();
+ Subsystem application = installSubsystemFromFile(root, APPLICATION_A);
+ try {
+ assertProvisionPolicy(application, true);
+ Subsystem composite = installSubsystemFromFile(application, COMPOSITE_A);
+ try {
+ assertProvisionPolicy(composite, false);
+ Subsystem feature = installSubsystemFromFile(composite, FEATURE_B);
+ try {
+ assertProvisionPolicy(feature, false);
+ assertConstituent(feature, BUNDLE_A);
+ assertNotConstituent(feature, BUNDLE_B);
+ assertNotConstituent(composite, BUNDLE_A);
+ assertNotConstituent(composite, BUNDLE_B);
+ assertConstituent(application, BUNDLE_A);
+ assertConstituent(application, BUNDLE_B);
+ assertNotConstituent(root, BUNDLE_A);
+ assertNotConstituent(root, BUNDLE_B);
+ }
+ finally {
+ uninstallSubsystemSilently(feature);
+ }
+ }
+ finally {
+ uninstallSubsystemSilently(composite);
+ }
+ }
+ finally {
+ uninstallSubsystemSilently(application);
+ }
+ }
+
+ @Test
+ public void testProvisionToRoot() throws Exception {
+ Subsystem root = getRootSubsystem();
+ Subsystem composite = installSubsystemFromFile(root, COMPOSITE_A);
+ try {
+ assertProvisionPolicy(composite, false);
+ Subsystem feature = installSubsystemFromFile(composite, FEATURE_B);
+ try {
+ assertProvisionPolicy(feature, false);
+ assertConstituent(feature, BUNDLE_A);
+ assertNotConstituent(feature, BUNDLE_B);
+ assertNotConstituent(composite, BUNDLE_A);
+ assertNotConstituent(composite, BUNDLE_B);
+ assertNotConstituent(root, BUNDLE_A);
+ assertConstituent(root, BUNDLE_B);
+ }
+ finally {
+ uninstallSubsystemSilently(feature);
+ }
+ }
+ finally {
+ uninstallSubsystemSilently(composite);
+ }
+ }
+
+ @Test
+ public void testProvisionToSelf() throws Exception {
+ Subsystem root = getRootSubsystem();
+ assertProvisionPolicy(root, true);
+ registerRepositoryService(BUNDLE_B);
+ Subsystem subsystem = installSubsystemFromFile(root, APPLICATION_A);
+ try {
+ assertProvisionPolicy(subsystem, true);
+ assertConstituent(subsystem, BUNDLE_A);
+ assertConstituent(subsystem, BUNDLE_B);
+ assertNotConstituent(root, BUNDLE_A);
+ assertNotConstituent(root, BUNDLE_B);
+ }
+ finally {
+ uninstallSubsystemSilently(subsystem);
+ }
+ }
+}
Modified: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java?rev=1300686&r1=1300685&r2=1300686&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java (original)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java Wed Mar 14 18:47:59 2012
@@ -16,6 +16,7 @@ package org.apache.aries.subsystem.itest
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.ops4j.pax.exam.CoreOptions.equinox;
@@ -38,12 +39,14 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import junit.framework.Assert;
-
import org.apache.aries.subsystem.core.ResourceHelper;
+import org.apache.aries.subsystem.core.archive.ProvisionPolicyDirective;
+import org.apache.aries.subsystem.core.archive.SubsystemTypeHeader;
import org.apache.aries.subsystem.core.internal.SubsystemIdentifier;
import org.apache.aries.subsystem.core.obr.felix.RepositoryAdminRepository;
+import org.apache.aries.subsystem.core.resource.BundleResource;
import org.apache.aries.subsystem.itests.util.RepositoryGenerator;
+import org.apache.aries.subsystem.itests.util.TestRepository;
import org.apache.aries.subsystem.itests.util.Utils;
import org.apache.aries.unittest.fixture.ArchiveFixture;
import org.apache.aries.unittest.fixture.ArchiveFixture.JarFixture;
@@ -64,6 +67,7 @@ import org.osgi.framework.Version;
import org.osgi.framework.namespace.IdentityNamespace;
import org.osgi.resource.Resource;
import org.osgi.service.repository.Repository;
+import org.osgi.service.repository.RepositoryContent;
import org.osgi.service.subsystem.Subsystem;
import org.osgi.service.subsystem.Subsystem.State;
import org.osgi.service.subsystem.SubsystemConstants;
@@ -203,7 +207,7 @@ public abstract class SubsystemTest exte
protected Collection<ServiceRegistration<?>> serviceRegistrations = new ArrayList<ServiceRegistration<?>>();
- public void setUp() {
+ public void setUp() throws Exception {
super.setUp();
new RepositoryGenerator(bundleContext).generateOBR();
serviceRegistrations.add(bundleContext.registerService(Repository.class, new RepositoryAdminRepository(getOsgiService(RepositoryAdmin.class)), null));
@@ -250,17 +254,21 @@ public abstract class SubsystemTest exte
assertTrue("Parent did not contain all children", parent.getChildren().containsAll(children));
}
+ protected void assertConstituent(Subsystem subsystem, String symbolicName) {
+ assertConstituent(subsystem, symbolicName, Version.emptyVersion);
+ }
+
+ protected void assertConstituent(Subsystem subsystem, String symbolicName, Version version) {
+ assertConstituent(subsystem, symbolicName, version, IdentityNamespace.TYPE_BUNDLE);
+ }
+
+ protected void assertContituent(Subsystem subsystem, String symbolicName, String type) {
+ assertConstituent(subsystem, symbolicName, Version.emptyVersion, type);
+ }
+
protected void assertConstituent(Subsystem subsystem, String symbolicName, Version version, String type) {
- for (Resource resource : subsystem.getConstituents()) {
- if (symbolicName.equals(ResourceHelper.getSymbolicNameAttribute(resource))) {
- if (version != null)
- assertVersion(version, ResourceHelper.getVersionAttribute(resource));
- if (type != null)
- assertEquals("Wrong type", type, ResourceHelper.getTypeAttribute(resource));
- return;
- }
- }
- Assert.fail("Constituent not found: " + symbolicName);
+ Resource constituent = getConstituent(subsystem, symbolicName, version, type);
+ assertNotNull("Constituent not found: " + symbolicName + ';' + version + ';' + type, constituent);
}
protected void assertConstituents(int size, Subsystem subsystem) {
@@ -336,6 +344,15 @@ public abstract class SubsystemTest exte
assertFalse("Parent contained child", parent.getChildren().contains(child));
}
+ protected void assertNotConstituent(Subsystem subsystem, String symbolicName) {
+ assertNotConstituent(subsystem, symbolicName, Version.emptyVersion, IdentityNamespace.TYPE_BUNDLE);
+ }
+
+ protected void assertNotConstituent(Subsystem subsystem, String symbolicName, Version version, String type) {
+ Resource constituent = getConstituent(subsystem, symbolicName, version, type);
+ assertNull("Constituent found: " + symbolicName + ';' + version + ';' + type, constituent);
+ }
+
protected void assertParent(Subsystem expected, Subsystem subsystem) {
for (Subsystem parent : subsystem.getParents()) {
if (parent.equals(expected))
@@ -345,6 +362,17 @@ public abstract class SubsystemTest exte
fail("Parent did not exist: " + expected.getSymbolicName());
}
+ protected void assertProvisionPolicy(Subsystem subsystem, boolean acceptsDependencies) {
+ String headerStr = subsystem.getSubsystemHeaders(null).get(SubsystemConstants.SUBSYSTEM_TYPE);
+ assertNotNull("Missing subsystem type header", headerStr);
+ SubsystemTypeHeader header = new SubsystemTypeHeader(headerStr);
+ ProvisionPolicyDirective directive = header.getProvisionPolicyDirective();
+ if (acceptsDependencies)
+ assertTrue("Subsystem does not accept dependencies", directive.isAcceptDependencies());
+ else
+ assertTrue("Subsystem accepts dependencies", directive.isRejectDependencies());
+ }
+
protected void assertRegionContextBundle(Subsystem s) {
Bundle b = getRegionContextBundle(s);
assertEquals("Not active", Bundle.ACTIVE, b.getState());
@@ -470,6 +498,14 @@ public abstract class SubsystemTest exte
write(symbolicName, bundle);
}
+ protected RepositoryContent createBundleRepositoryContent(String file) throws Exception {
+ return createBundleRepositoryContent(new File(file));
+ }
+
+ protected RepositoryContent createBundleRepositoryContent(File file) throws Exception {
+ return BundleResource.newInstance(file.toURI().toURL());
+ }
+
protected static void createManifest(String name, Map<String, String> headers) throws IOException {
ManifestFixture manifest = ArchiveFixture.newJar().manifest();
for (Entry<String, String> header : headers.entrySet()) {
@@ -492,6 +528,23 @@ public abstract class SubsystemTest exte
write(name, fixture);
}
+ protected Resource getConstituent(Subsystem subsystem, String symbolicName, Version version, String type) {
+ for (Resource resource : subsystem.getConstituents()) {
+ if (symbolicName.equals(ResourceHelper.getSymbolicNameAttribute(resource))) {
+ if (version == null)
+ version = Version.emptyVersion;
+ if (version.equals(ResourceHelper.getVersionAttribute(resource))) {
+ if (type == null)
+ type = IdentityNamespace.TYPE_BUNDLE;
+ if (type.equals(ResourceHelper.getTypeAttribute(resource))) {
+ return resource;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
protected Bundle getRegionContextBundle(Subsystem subsystem) {
BundleContext bc = subsystem.getBundleContext();
assertNotNull("No region context bundle", bc);
@@ -558,7 +611,7 @@ public abstract class SubsystemTest exte
protected Subsystem installSubsystem(Subsystem parent, String location, InputStream content) throws Exception {
subsystemEvents.clear();
- Subsystem subsystem = getRootSubsystem().install(location, content);
+ Subsystem subsystem = parent.install(location, content);
assertSubsystemNotNull(subsystem);
assertEvent(subsystem, State.INSTALLING, 5000);
assertEvent(subsystem, State.INSTALLED, 5000);
@@ -568,10 +621,33 @@ public abstract class SubsystemTest exte
assertState(State.INSTALLED, subsystem);
assertLocation(location, subsystem);
assertId(subsystem);
- assertDirectory(subsystem);
+ // TODO This does not take into account nested directories.
+// assertDirectory(subsystem);
return subsystem;
}
+ protected void registerRepositoryService(Repository repository) {
+ serviceRegistrations.add(bundleContext.registerService(
+ Repository.class, repository, null));
+ }
+
+ protected void registerRepositoryService(Resource...resources) {
+ TestRepository.Builder builder = new TestRepository.Builder();
+ for (Resource resource : resources) {
+ builder.resource(resource);
+ }
+ registerRepositoryService(builder.build());
+ }
+
+ protected void registerRepositoryService(String...files) throws Exception {
+ Resource[] resources = new Resource[files.length];
+ int i = 0;
+ for (String file : files) {
+ resources[i++] = (Resource)createBundleRepositoryContent(file);
+ }
+ registerRepositoryService(resources);
+ }
+
protected void startBundle(Bundle bundle) throws BundleException {
startBundle(bundle, getRootSubsystem());
}
@@ -592,6 +668,11 @@ public abstract class SubsystemTest exte
assertState(State.ACTIVE, subsystem);
}
+ protected void stopAndUninstallSubsystemSilently(Subsystem subsystem) {
+ stopSubsystemSilently(subsystem);
+ uninstallSubsystemSilently(subsystem);
+ }
+
protected void stopSubsystem(Subsystem subsystem) throws Exception {
assertState(State.ACTIVE, subsystem);
subsystemEvents.clear();
@@ -630,6 +711,8 @@ public abstract class SubsystemTest exte
}
protected void uninstallSubsystemSilently(Subsystem subsystem) {
+ if (subsystem == null)
+ return;
try {
uninstallSubsystem(subsystem);
}