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/04/12 01:26:49 UTC
svn commit: r1325064 - in
/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core:
archive/ internal/ obr/
Author: jwross
Date: Wed Apr 11 23:26:48 2012
New Revision: 1325064
URL: http://svn.apache.org/viewvc?rev=1325064&view=rev
Log:
ARIES-825: Update subsystems to latest Subsystem, Resolver, and Repository APIs.
Added initial support for Preferred-Provider.
Added:
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/PreferredProviderHeader.java
Removed:
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/
Modified:
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/Grammar.java
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/HeaderFactory.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/TypeAttribute.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/Constants.java
aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEnvironment.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/internal/SubsystemResolverHook.java
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=1325064&r1=1325063&r2=1325064&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 Apr 11 23:26:48 2012
@@ -17,15 +17,10 @@ import java.util.jar.Attributes;
import java.util.jar.Manifest;
import org.apache.aries.subsystem.core.internal.Activator;
-import org.apache.aries.subsystem.core.internal.AriesSubsystem;
import org.apache.aries.subsystem.core.internal.OsgiIdentityRequirement;
import org.apache.aries.subsystem.core.internal.SubsystemEnvironment;
import org.apache.aries.util.manifest.ManifestProcessor;
import org.osgi.framework.Constants;
-import org.osgi.framework.namespace.BundleNamespace;
-import org.osgi.framework.namespace.PackageNamespace;
-import org.osgi.framework.wiring.BundleRevision;
-import org.osgi.resource.Requirement;
import org.osgi.resource.Resource;
import org.osgi.resource.Wire;
import org.osgi.service.subsystem.SubsystemConstants;
@@ -106,7 +101,7 @@ public class DeploymentManifest {
Map<String, Header<?>> headers;
if (deploymentManifest == null // We're generating a new deployment manifest.
|| (deploymentManifest != null && overwrite)) { // A deployment manifest already exists but overwriting it with subsystem manifest content is desired.
- headers = new HashMap<String, Header<?>>();
+ headers = computeHeaders(subsystemManifest);
Collection<Resource> resources = new HashSet<Resource>();
SubsystemContentHeader contentHeader = subsystemManifest.getSubsystemContentHeader();
Map<Resource, List<Wire>> resolution = null;
@@ -138,48 +133,6 @@ public class DeploymentManifest {
if (!provisionResource.isEmpty())
headers.put(PROVISION_RESOURCE, ProvisionResourceHeader.newInstance(provisionResource));
}
- headers.put(SUBSYSTEM_SYMBOLICNAME, subsystemManifest.getSubsystemSymbolicNameHeader());
- headers.put(SUBSYSTEM_VERSION, subsystemManifest.getSubsystemVersionHeader());
- SubsystemTypeHeader typeHeader = subsystemManifest.getSubsystemTypeHeader();
- if (typeHeader.isApplication()) {
- if (resolution != null) {
- Header<?> header = computeImportPackageHeader(resolution, deployedContent, acceptDependencies);
- if (header != null)
- headers.put(IMPORT_PACKAGE, header);
- header = computeRequireCapabilityHeader(resolution, deployedContent, acceptDependencies);
- if (header != null)
- headers.put(REQUIRE_CAPABILITY, header);
- header = computeRequireBundleHeader(resolution, deployedContent, acceptDependencies);
- if (header != null)
- headers.put(REQUIRE_BUNDLE, header);
- }
- // TODO Compute additional headers for an application.
- }
- else if (typeHeader.isComposite()) {
- Header<?> header = subsystemManifest.getImportPackageHeader();
- if (header != null)
- headers.put(IMPORT_PACKAGE, header);
- header = subsystemManifest.getRequireCapabilityHeader();
- if (header != null)
- headers.put(REQUIRE_CAPABILITY, header);
- header = subsystemManifest.getSubsystemImportServiceHeader();
- if (header != null)
- headers.put(SUBSYSTEM_IMPORTSERVICE, header);
- header = subsystemManifest.getRequireBundleHeader();
- if (header != null)
- headers.put(REQUIRE_BUNDLE, header);
- header = subsystemManifest.getExportPackageHeader();
- if (header != null)
- headers.put(EXPORT_PACKAGE, header);
- header = subsystemManifest.getProvideCapabilityHeader();
- if (header != null)
- headers.put(PROVIDE_CAPABILITY, header);
- header = subsystemManifest.getSubsystemExportServiceHeader();
- if (header != null)
- headers.put(SUBSYSTEM_EXPORTSERVICE, header);
- // TODO Compute additional headers for a composite.
- }
- // Features require no additional headers.
}
else {
headers = new HashMap<String, Header<?>>(deploymentManifest.getHeaders());
@@ -248,88 +201,7 @@ public class DeploymentManifest {
manifest.write(out);
}
- private static ImportPackageHeader computeImportPackageHeader(
- Map<Resource, List<Wire>> resolution,
- Collection<Resource> content,
- boolean acceptDependencies) {
- Collection<ImportPackageHeader.Clause> clauses = new ArrayList<ImportPackageHeader.Clause>();
- for (Entry<Resource, List<Wire>> entry : resolution.entrySet()) {
- for (Wire wire : entry.getValue()) {
- Resource provider = wire.getProvider();
- if (content.contains(provider))
- // If the provider is a content resource, we don't need an import.
- continue;
- // The provider is a dependency that is already provisioned or needs provisioning.
- if (acceptDependencies && !((provider instanceof BundleRevision) || (provider instanceof AriesSubsystem)))
- // If the application accepts dependencies and the provider is a dependency that needs provisioning,
- // we don't need an import.
- continue;
- // For all other cases, we need an import.
- Requirement requirement = wire.getRequirement();
- if (PackageNamespace.PACKAGE_NAMESPACE.equals(requirement.getNamespace())) {
- clauses.add(new ImportPackageHeader.Clause(requirement));
- }
- }
- }
- if (clauses.isEmpty())
- return null;
- return new ImportPackageHeader(clauses);
- }
-
- private static RequireBundleHeader computeRequireBundleHeader(
- Map<Resource, List<Wire>> resolution,
- Collection<Resource> content,
- boolean acceptDependencies) {
- Collection<RequireBundleHeader.Clause> clauses = new ArrayList<RequireBundleHeader.Clause>();
- for (Entry<Resource, List<Wire>> entry : resolution.entrySet()) {
- for (Wire wire : entry.getValue()) {
- Resource provider = wire.getProvider();
- if (content.contains(provider))
- // If the provider is a content resource, we don't need an import.
- continue;
- // The provider is a dependency that is already provisioned or needs provisioning.
- if (acceptDependencies && !((provider instanceof BundleRevision) || (provider instanceof AriesSubsystem)))
- // If the application accepts dependencies and the provider is a dependency that needs provisioning,
- // we don't need an import.
- continue;
- // For all other cases, we need an import.
- Requirement requirement = wire.getRequirement();
- if (BundleNamespace.BUNDLE_NAMESPACE.equals(requirement.getNamespace())) {
- clauses.add(new RequireBundleHeader.Clause(requirement));
- }
- }
- }
- if (clauses.isEmpty())
- return null;
- return new RequireBundleHeader(clauses);
- }
-
- private static RequireCapabilityHeader computeRequireCapabilityHeader(
- Map<Resource, List<Wire>> resolution,
- Collection<Resource> content,
- boolean acceptDependencies) {
- Collection<RequireCapabilityHeader.Clause> clauses = new ArrayList<RequireCapabilityHeader.Clause>();
- for (Entry<Resource, List<Wire>> entry : resolution.entrySet()) {
- for (Wire wire : entry.getValue()) {
- Resource provider = wire.getProvider();
- if (content.contains(provider))
- // If the provider is a content resource, we don't need an imported capability.
- continue;
- // The provider is a dependency that is already provisioned or needs provisioning.
- if (acceptDependencies && !((provider instanceof BundleRevision) || (provider instanceof AriesSubsystem)))
- // If the application accepts dependencies and the provider is a dependency that needs provisioning,
- // we don't need an import.
- continue;
- // For all other cases, we need an import.
- Requirement requirement = wire.getRequirement();
- // TODO Not sure if the startsWith check will be sufficient.
- if (!requirement.getNamespace().startsWith("osgi.")) {
- clauses.add(new RequireCapabilityHeader.Clause(requirement));
- }
- }
- }
- if (clauses.isEmpty())
- return null;
- return new RequireCapabilityHeader(clauses);
+ private Map<String, Header<?>> computeHeaders(SubsystemManifest manifest) {
+ return new HashMap<String, Header<?>>(manifest.getHeaders());
}
}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/Grammar.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/Grammar.java?rev=1325064&r1=1325063&r2=1325064&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/Grammar.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/Grammar.java Wed Apr 11 23:26:48 2012
@@ -137,6 +137,9 @@ public interface Grammar {
public static final String SUBSYSTEM_EXPORTSERVICE = SERVICE + "(?:,\\s*(?:" + SERVICE + "))*";
public static final String SUBSYSTEM_IMPORTSERVICE = SERVICE + "(?:,\\s*(?:" + SERVICE + "))*";
+ public static final String RESOURCE = SYMBOLICNAME + "(?:;\\s*(?:" + PARAMETER + "))*";
+ public static final String PREFERRED_PROVIDER = RESOURCE + "(?:,\\s*(?:" + RESOURCE + "))*";
+
/*
* number ::= digit+
* version ::= major( '.' minor ( '.' micro ( '.' qualifier )? )? )?
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/HeaderFactory.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/HeaderFactory.java?rev=1325064&r1=1325063&r2=1325064&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/HeaderFactory.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/HeaderFactory.java Wed Apr 11 23:26:48 2012
@@ -109,6 +109,8 @@ public class HeaderFactory {
return new BundleSymbolicNameHeader(value);
if (BundleVersionHeader.NAME.equals(name))
return new BundleVersionHeader(value);
+ if (PreferredProviderHeader.NAME.equals(name))
+ return new PreferredProviderHeader(value);
return new GenericHeader(name, value);
}
Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/PreferredProviderHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/PreferredProviderHeader.java?rev=1325064&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/PreferredProviderHeader.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/PreferredProviderHeader.java Wed Apr 11 23:26:48 2012
@@ -0,0 +1,208 @@
+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.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.aries.subsystem.core.ResourceHelper;
+import org.osgi.framework.VersionRange;
+import org.osgi.resource.Resource;
+import org.osgi.service.subsystem.SubsystemConstants;
+
+public class PreferredProviderHeader implements RequirementHeader<PreferredProviderHeader.Clause> {
+ public static class Clause implements org.apache.aries.subsystem.core.archive.Clause {
+ public static final String ATTRIBUTE_TYPE = TypeAttribute.NAME;
+ public static final String ATTRIBUTE_VERSION = VersionAttribute.NAME;
+
+ private static final Pattern PATTERN_SYMBOLICNAME = Pattern.compile('(' + Grammar.SYMBOLICNAME + ")(?=;|\\z)");
+ private static final Pattern PATTERN_PARAMETER = Pattern.compile('(' + Grammar.PARAMETER + ")(?=;|\\z)");
+
+ private static void fillInDefaults(Map<String, Parameter> parameters) {
+ Parameter parameter = parameters.get(ATTRIBUTE_VERSION);
+ if (parameter == null)
+ parameters.put(ATTRIBUTE_VERSION, VersionAttribute.DEFAULT);
+ parameter = parameters.get(ATTRIBUTE_TYPE);
+ if (parameter == null)
+ parameters.put(ATTRIBUTE_TYPE, TypeAttribute.newInstance(SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE));
+ }
+
+ private final String path;
+ private final Map<String, Parameter> parameters = new HashMap<String, Parameter>();
+
+ public Clause(String clause) {
+ Matcher matcher = PATTERN_SYMBOLICNAME.matcher(clause);
+ if (!matcher.find())
+ throw new IllegalArgumentException("Missing resource path: " + clause);
+ path = matcher.group();
+ matcher.usePattern(PATTERN_PARAMETER);
+ while (matcher.find()) {
+ Parameter parameter = ParameterFactory.create(matcher.group());
+ parameters.put(parameter.getName(), parameter);
+ }
+ fillInDefaults(parameters);
+ }
+
+ public boolean contains(Resource resource) {
+ return getSymbolicName().equals(
+ ResourceHelper.getSymbolicNameAttribute(resource))
+ && getVersionRange().includes(
+ ResourceHelper.getVersionAttribute(resource))
+ && getType().equals(
+ ResourceHelper.getTypeAttribute(resource));
+ }
+
+ @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 String getSymbolicName() {
+ return path;
+ }
+
+ public String getType() {
+ return (String)getAttribute(ATTRIBUTE_TYPE).getValue();
+ }
+
+ public VersionRange getVersionRange() {
+ Attribute attribute = getAttribute(ATTRIBUTE_VERSION);
+ if (attribute instanceof VersionRangeAttribute)
+ return ((VersionRangeAttribute)attribute).getVersionRange();
+ return new VersionRange(attribute.getValue().toString());
+ }
+
+ @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 NAME = SubsystemConstants.PREFERRED_PROVIDER;
+
+ private static final Pattern PATTERN = Pattern.compile('(' + Grammar.PREFERRED_PROVIDER + ")(?=,|\\z)");
+
+ private static Collection<Clause> processHeader(String header) {
+ Matcher matcher = PATTERN.matcher(header);
+ Set<Clause> clauses = new HashSet<Clause>();
+ while (matcher.find())
+ clauses.add(new Clause(matcher.group()));
+ return clauses;
+ }
+
+ private final Set<Clause> clauses;
+
+ public PreferredProviderHeader(Collection<Clause> clauses) {
+ if (clauses.isEmpty())
+ throw new IllegalArgumentException("A " + NAME + " header must have at least one clause");
+ this.clauses = new HashSet<Clause>(clauses);
+ }
+
+ public PreferredProviderHeader(String value) {
+ this(processHeader(value));
+ }
+
+ public boolean contains(Resource resource) {
+ for (Clause clause : getClauses())
+ if (clause.contains(resource))
+ return true;
+ return false;
+ }
+
+ @Override
+ public Collection<PreferredProviderHeader.Clause> getClauses() {
+ return Collections.unmodifiableSet(clauses);
+ }
+
+ @Override
+ public String getName() {
+ return NAME;
+ }
+
+ @Override
+ public String getValue() {
+ return toString();
+ }
+
+ @Override
+ public List<RequireBundleRequirement> toRequirements(Resource resource) {
+ List<RequireBundleRequirement> requirements = new ArrayList<RequireBundleRequirement>(clauses.size());
+// for (Clause clause : clauses)
+// requirements.add(clause.toRequirement(resource));
+ return requirements;
+ }
+
+ @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/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=1325064&r1=1325063&r2=1325064&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 Apr 11 23:26:48 2012
@@ -183,6 +183,10 @@ public class SubsystemManifest {
return (ImportPackageHeader)getHeaders().get(IMPORT_PACKAGE);
}
+ public PreferredProviderHeader getPreferredProviderHeader() {
+ return (PreferredProviderHeader)getHeaders().get(PREFERRED_PROVIDER);
+ }
+
public ProvideCapabilityHeader getProvideCapabilityHeader() {
return (ProvideCapabilityHeader)getHeaders().get(PROVIDE_CAPABILITY);
}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/TypeAttribute.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/TypeAttribute.java?rev=1325064&r1=1325063&r2=1325064&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/TypeAttribute.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/TypeAttribute.java Wed Apr 11 23:26:48 2012
@@ -13,10 +13,12 @@
*/
package org.apache.aries.subsystem.core.archive;
+import org.osgi.framework.namespace.IdentityNamespace;
+
public class TypeAttribute extends AbstractAttribute {
public static final TypeAttribute DEFAULT = new TypeAttribute();
// TODO Add to constants.
- public static final String DEFAULT_VALUE = "osgi.bundle";
+ public static final String DEFAULT_VALUE = IdentityNamespace.TYPE_BUNDLE;
// TODO Add to constants.
public static final String NAME = "type";
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=1325064&r1=1325063&r2=1325064&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 Apr 11 23:26:48 2012
@@ -857,11 +857,10 @@ public class AriesSubsystem implements S
}
private DeploymentManifest getDeploymentManifest() throws IOException, URISyntaxException {
-// if (archive.getDeploymentManifest() == null) {
+ if (archive.getDeploymentManifest() == null)
archive.setDeploymentManifest(new DeploymentManifest(
archive.getDeploymentManifest(),
archive.getSubsystemManifest(),
-// environment,
new SubsystemEnvironment(this),
autostart,
id,
@@ -869,11 +868,12 @@ public class AriesSubsystem implements S
location,
true,
false));
-// }
return archive.getDeploymentManifest();
}
private synchronized void install(Coordination coordination, AriesSubsystem parent) throws Exception {
+ if (!State.INSTALLING.equals(getState()))
+ return;
if (!isFeature())
RegionContextBundleHelper.installRegionContextBundle(this);
Activator.getInstance().getSubsystemServiceRegistrar().register(this, parent);
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Constants.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Constants.java?rev=1325064&r1=1325063&r2=1325064&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Constants.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Constants.java Wed Apr 11 23:26:48 2012
@@ -1,9 +1,13 @@
package org.apache.aries.subsystem.core.internal;
+import org.osgi.framework.namespace.IdentityNamespace;
+
public class Constants {
public static final String BundleSymbolicName = org.osgi.framework.Constants.BUNDLE_SYMBOLICNAME;
public static final String BundleVersion = org.osgi.framework.Constants.BUNDLE_VERSION;
public static final String RegionContextBundleSymbolicNamePrefix = "org.osgi.service.subsystem.region.context.";
+ public static final String ResourceTypeBundle = IdentityNamespace.TYPE_BUNDLE;
+ public static final String ResourceTypeFragment = IdentityNamespace.TYPE_FRAGMENT;
public static final String SubsystemServicePropertyRegions = "org.apache.aries.subsystem.service.regions";
private Constants() {}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEnvironment.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEnvironment.java?rev=1325064&r1=1325063&r2=1325064&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEnvironment.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEnvironment.java Wed Apr 11 23:26:48 2012
@@ -20,7 +20,6 @@ import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedSet;
@@ -28,6 +27,7 @@ import java.util.TreeSet;
import org.apache.aries.subsystem.core.Environment;
import org.apache.aries.subsystem.core.ResourceHelper;
+import org.apache.aries.subsystem.core.archive.PreferredProviderHeader;
import org.eclipse.equinox.region.Region;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
@@ -48,6 +48,64 @@ import org.slf4j.LoggerFactory;
* So does the locating of providers for feature content with respect to children of the first parent that is not a feature.
*/
public class SubsystemEnvironment implements Environment {
+ private static final class Comparator implements java.util.Comparator<Capability> {
+ private final AriesSubsystem subsystem;
+
+ public Comparator(AriesSubsystem subsystem) {
+ this.subsystem = subsystem;
+ }
+
+ @Override
+ public int compare(Capability c1, Capability c2) {
+ if (logger.isDebugEnabled())
+ logger.debug(LOG_ENTRY, "compare", new Object[]{c1, c2});
+ int result = comparePreferredProvider(c1, c2);
+ if (result == 0)
+ result = compareRuntimeResource(c1, c2);
+ logger.debug(LOG_EXIT, "compare", result);
+ return result;
+ }
+
+ private int comparePreferredProvider(Capability c1, Capability c2) {
+ boolean pp1 = isPreferredProvider(c1);
+ boolean pp2 = isPreferredProvider(c2);
+ if (pp1 && !pp2)
+ return -1;
+ else if (!pp1 && pp2)
+ return 1;
+ return 0;
+ }
+
+ private int compareRuntimeResource(Capability c1, Capability c2) {
+ boolean rr1 = isRuntimeResource(c1);
+ boolean rr2 = isRuntimeResource(c2);
+ if (rr1 && !rr2)
+ return -1;
+ else if (!rr1 && rr2)
+ return 1;
+ return 0;
+ }
+
+ private boolean isPreferredProvider(Resource resource) {
+ PreferredProviderHeader header = subsystem.getArchive().getSubsystemManifest().getPreferredProviderHeader();
+ if (header == null)
+ return false;
+ return header.contains(resource);
+ }
+
+ private boolean isPreferredProvider(Capability capability) {
+ return isPreferredProvider(capability.getResource());
+ }
+
+ private boolean isRuntimeResource(Resource resource) {
+ return resource instanceof BundleRevision || resource instanceof AriesSubsystem;
+ }
+
+ private boolean isRuntimeResource(Capability capability) {
+ return isRuntimeResource(capability.getResource());
+ }
+ }
+
private static final Logger logger = LoggerFactory.getLogger(SubsystemEnvironment.class);
// private final Set<Resource> resources = new HashSet<Resource>();
@@ -71,23 +129,7 @@ public class SubsystemEnvironment implem
public SortedSet<Capability> findProviders(Requirement requirement) {
logger.debug(LOG_ENTRY, "findProviders", requirement);
// TODO Need a more robust comparator. This is just a temporary place holder.
- SortedSet<Capability> capabilities = new TreeSet<Capability>(
- new Comparator<Capability>() {
- @Override
- public int compare(Capability capability1, Capability capability2) {
- if (logger.isDebugEnabled())
- logger.debug(LOG_ENTRY, "compare", new Object[]{capability1, capability2});
- int result = 0;
- boolean br1 = capability1.getResource() instanceof BundleRevision;
- boolean br2 = capability2.getResource() instanceof BundleRevision;
- if (br1 && !br2)
- result = -1;
- else if (!br1 && br2)
- result = 1;
- logger.debug(LOG_EXIT, "compare", result);
- return result;
- }
- });
+ SortedSet<Capability> capabilities = new TreeSet<Capability>(new Comparator(subsystem));
if (requirement instanceof OsgiIdentityRequirement) {
logger.debug("The requirement is an instance of OsgiIdentityRequirement");
// TODO Consider returning only the first capability matched by the requirement in this case.
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=1325064&r1=1325063&r2=1325064&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 Apr 11 23:26:48 2012
@@ -1,5 +1,6 @@
package org.apache.aries.subsystem.core.internal;
+import org.apache.aries.subsystem.core.archive.PreferredProviderHeader;
import org.apache.aries.subsystem.core.archive.SubsystemContentHeader;
import org.apache.aries.subsystem.core.archive.SubsystemManifest;
import org.osgi.framework.VersionRange;
@@ -8,6 +9,7 @@ import org.osgi.service.subsystem.Subsys
public class SubsystemManifestValidator {
public static void validate(AriesSubsystem subsystem, SubsystemManifest manifest) {
+ validatePreferredProviderHeader(manifest.getPreferredProviderHeader());
if (subsystem.isComposite()) {
SubsystemContentHeader header = manifest.getSubsystemContentHeader();
if (header == null)
@@ -26,6 +28,7 @@ public class SubsystemManifestValidator
}
}
+ // TODO Replace this with the new isExact() method on OSGi VersionRange.
private static boolean isExactVersion(VersionRange range) {
if (range.getLeftType() == VersionRange.LEFT_CLOSED
&& range.getLeft().equals(range.getRight())
@@ -34,4 +37,16 @@ public class SubsystemManifestValidator
}
return false;
}
+
+ private static void validatePreferredProviderHeader(PreferredProviderHeader header) {
+ if (header == null)
+ return;
+ for (PreferredProviderHeader.Clause clause : header.getClauses()) {
+ String type = (String)clause.getAttribute(PreferredProviderHeader.Clause.ATTRIBUTE_TYPE).getValue();
+ if (!(SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE.equals(type) ||
+ SubsystemConstants.SUBSYSTEM_TYPE_FEATURE.equals(type) ||
+ Constants.ResourceTypeBundle.equals(type)))
+ throw new SubsystemException("Unsupported " + PreferredProviderHeader.NAME + " type: " + type);
+ }
+ }
}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHook.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHook.java?rev=1325064&r1=1325063&r2=1325064&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHook.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHook.java Wed Apr 11 23:26:48 2012
@@ -13,13 +13,16 @@
*/
package org.apache.aries.subsystem.core.internal;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
+import org.apache.aries.subsystem.core.archive.PreferredProviderHeader;
import org.osgi.framework.hooks.resolver.ResolverHook;
import org.osgi.framework.wiring.BundleCapability;
import org.osgi.framework.wiring.BundleRequirement;
import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.resource.Resource;
import org.osgi.service.subsystem.Subsystem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -32,7 +35,24 @@ public class SubsystemResolverHook imple
}
public void filterMatches(BundleRequirement requirement, Collection<BundleCapability> candidates) {
- // noop
+ // Filter out candidates that don't come from preferred providers when
+ // there is at least one preferred provider.
+ // (1) Find the subsystem(s) containing requirement.getResource() as a
+ // constituent.
+ Collection<AriesSubsystem> requirers = AriesSubsystem.getSubsystems(requirement.getResource());
+ // (2) For each candidate, ask each subsystem if the candidate or any of
+ // the candidate's containing subsystems is a preferred provider. If at
+ // least one preferred provider exists, filter out all other candidates
+ // that are not also preferred providers.
+ Collection<BundleCapability> preferredProviders = new ArrayList<BundleCapability>(candidates.size());
+ for (BundleCapability candidate : candidates)
+ for (AriesSubsystem subsystem : requirers) {
+ PreferredProviderHeader header = subsystem.getArchive().getSubsystemManifest().getPreferredProviderHeader();
+ if (header != null && (header.contains(candidate.getResource()) || isResourceConstituentOfPreferredSubsystem(candidate.getResource(), subsystem)))
+ preferredProviders.add(candidate);
+ }
+ if (!preferredProviders.isEmpty())
+ candidates.retainAll(preferredProviders);
}
public void filterResolvable(Collection<BundleRevision> candidates) {
@@ -65,4 +85,12 @@ public class SubsystemResolverHook imple
public void filterSingletonCollisions(BundleCapability singleton, Collection<BundleCapability> collisionCandidates) {
// noop
}
+
+ private boolean isResourceConstituentOfPreferredSubsystem(Resource resource, AriesSubsystem preferer) {
+ Collection<AriesSubsystem> subsystems = AriesSubsystem.getSubsystems(resource);
+ for (AriesSubsystem subsystem : subsystems)
+ if (preferer.getArchive().getSubsystemManifest().getPreferredProviderHeader().contains(subsystem))
+ return true;
+ return false;
+ }
}