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/02/28 00:16:45 UTC

svn commit: r1294392 - 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-itests/src/test/java/org/apache/aries/subsystem/ite...

Author: jwross
Date: Mon Feb 27 23:16:45 2012
New Revision: 1294392

URL: http://svn.apache.org/viewvc?rev=1294392&view=rev
Log:
ARIES-825: Update subsystems to latest Subsystem, Resolver, and Repository APIs.

(1) Initial support for Require-Bundle header in composites.
(2) Added new composite test.

Added:
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleVersionAttribute.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireBundleHeader.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireBundleRequirement.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/VisibilityDirective.java
Modified:
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/AttributeFactory.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/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/internal/AriesSubsystem.java
    aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/CompositeTest.java

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/AttributeFactory.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/AttributeFactory.java?rev=1294392&r1=1294391&r2=1294392&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/AttributeFactory.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/AttributeFactory.java Mon Feb 27 23:16:45 2012
@@ -27,6 +27,8 @@ public class AttributeFactory {
 			return new TypeAttribute(value);
 		if (DeployedVersionAttribute.NAME.equals(name))
 			return new DeployedVersionAttribute(value);
+		if (BundleVersionAttribute.NAME.equals(name))
+			return new BundleVersionAttribute(value);
 		return new GenericAttribute(name, value);
 	}
 }

Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleVersionAttribute.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleVersionAttribute.java?rev=1294392&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleVersionAttribute.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleVersionAttribute.java Mon Feb 27 23:16:45 2012
@@ -0,0 +1,45 @@
+/*
+ * Licensed 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.aries.subsystem.core.archive;
+
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+import org.osgi.framework.VersionRange;
+
+public class BundleVersionAttribute extends AbstractAttribute {
+	public static final String NAME = Constants.BUNDLE_VERSION_ATTRIBUTE;
+	
+	private final VersionRange range;
+	
+	public BundleVersionAttribute() {
+		this(Version.emptyVersion.toString());
+	}
+			
+	public BundleVersionAttribute(String value) {
+		this(new VersionRange(value));
+	}
+	
+	public BundleVersionAttribute(VersionRange range) {
+		super(NAME, range.toString());
+		this.range = range;
+	}
+	
+	public StringBuilder appendToFilter(StringBuilder builder) {
+		return builder.append(range.toFilterString(NAME));
+	}
+
+	public VersionRange getVersionRange() {
+		return range;
+	}
+}

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=1294392&r1=1294391&r2=1294392&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 Mon Feb 27 23:16:45 2012
@@ -127,6 +127,9 @@ public class DeploymentManifest {
 				header = subsystemManifest.getSubsystemImportServiceHeader();
 				if (header != null)
 					headers.put(SUBSYSTEM_IMPORTSERVICE, header);
+				header = subsystemManifest.getRequireBundleHeader();
+				if (header != null)
+					headers.put(REQUIRE_BUNDLE, header);
 				// TODO Compute additional headers for a composite. 
 			}
 			// Features require no additional headers.
@@ -158,6 +161,10 @@ public class DeploymentManifest {
 		return (ProvisionResourceHeader)getHeaders().get(PROVISION_RESOURCE);
 	}
 	
+	public RequireBundleHeader getRequireBundleHeader() {
+		return (RequireBundleHeader)getHeaders().get(REQUIRE_BUNDLE);
+	}
+	
 	public RequireCapabilityHeader getRequireCapabilityHeader() {
 		return (RequireCapabilityHeader)getHeaders().get(REQUIRE_CAPABILITY);
 	}

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=1294392&r1=1294391&r2=1294392&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 Mon Feb 27 23:16:45 2012
@@ -23,6 +23,8 @@ public class DirectiveFactory {
 			return new FilterDirective(value);
 		if (EffectiveDirective.NAME.equals(name))
 			return EffectiveDirective.getInstance(value);
+		if (VisibilityDirective.NAME.equals(name))
+			return VisibilityDirective.getInstance(value);
 		return new GenericDirective(name, value);
 	}
 }

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=1294392&r1=1294391&r2=1294392&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 Mon Feb 27 23:16:45 2012
@@ -119,6 +119,9 @@ public interface Grammar {
 	public static final String REQUIREMENT = NAMESPACE + "(?:;\\s*(?:" + PARAMETER + "))*";
 	public static final String REQUIRE_CAPABILITY = REQUIREMENT + "(?:,\\s*(?:" + REQUIREMENT + "))*";
 	
+	public static final String BUNDLE_DESCRIPTION = SYMBOLICNAME + "(?:;\\s*(?:" + PARAMETER + "))*";
+	public static final String REQUIRE_BUNDLE = BUNDLE_DESCRIPTION + "(?:,\\s*(?:" + BUNDLE_DESCRIPTION + "))*";
+	
 	/*
 	 * 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=1294392&r1=1294391&r2=1294392&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 Mon Feb 27 23:16:45 2012
@@ -99,6 +99,8 @@ public class HeaderFactory {
 			return new RequireCapabilityHeader(value);
 		if (SubsystemImportServiceHeader.NAME.equals(name))
 			return new SubsystemImportServiceHeader(value);
+		if (RequireBundleHeader.NAME.equals(name))
+			return new RequireBundleHeader(value);
 		return new GenericHeader(name, value);
 			
 	}

Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireBundleHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireBundleHeader.java?rev=1294392&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireBundleHeader.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireBundleHeader.java Mon Feb 27 23:16:45 2012
@@ -0,0 +1,160 @@
+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.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.osgi.framework.Constants;
+
+public class RequireBundleHeader implements Header<RequireBundleHeader.Clause> {
+	public static class Clause implements org.apache.aries.subsystem.core.archive.Clause {
+		public static final String ATTRIBUTE_BUNDLEVERSION = Constants.BUNDLE_VERSION_ATTRIBUTE;
+		public static final String DIRECTIVE_RESOLUTION = Constants.RESOLUTION_DIRECTIVE;
+		public static final String DIRECTIVE_VISIBILITY = Constants.VISIBILITY_DIRECTIVE;
+		
+		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(DIRECTIVE_VISIBILITY);
+			if (parameter == null)
+				parameters.put(DIRECTIVE_VISIBILITY, VisibilityDirective.PRIVATE);
+			parameter = parameters.get(DIRECTIVE_RESOLUTION);
+			if (parameter == null)
+				parameters.put(DIRECTIVE_RESOLUTION, ResolutionDirective.MANDATORY);
+		}
+		
+		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 bundle description 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);
+		}
+		
+		@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;
+		}
+		
+		@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 = Constants.REQUIRE_BUNDLE;
+
+	private static final Pattern PATTERN = Pattern.compile('(' + Grammar.BUNDLE_DESCRIPTION + ")(?=,|\\z)");
+	
+	private final Set<Clause> clauses = new HashSet<Clause>();
+	
+	public RequireBundleHeader(String value) {
+		Matcher matcher = PATTERN.matcher(value);
+		while (matcher.find())
+			clauses.add(new Clause(matcher.group()));
+		if (clauses.isEmpty())
+			throw new IllegalArgumentException("A " + NAME + " header must have at least one clause");
+	}
+	
+	@Override
+	public Collection<RequireBundleHeader.Clause> getClauses() {
+		return Collections.unmodifiableSet(clauses);
+	}
+
+	@Override
+	public String getName() {
+		return NAME;
+	}
+
+	@Override
+	public String getValue() {
+		return toString();
+	}
+	
+	@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();
+	}
+}

Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireBundleRequirement.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireBundleRequirement.java?rev=1294392&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireBundleRequirement.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireBundleRequirement.java Mon Feb 27 23:16:45 2012
@@ -0,0 +1,52 @@
+package org.apache.aries.subsystem.core.archive;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.aries.subsystem.core.resource.AbstractRequirement;
+import org.osgi.framework.namespace.BundleNamespace;
+import org.osgi.resource.Resource;
+
+public class RequireBundleRequirement extends AbstractRequirement {
+	public static final String DIRECTIVE_FILTER = BundleNamespace.REQUIREMENT_FILTER_DIRECTIVE;
+	public static final String NAMESPACE = BundleNamespace.BUNDLE_NAMESPACE;
+	
+	private final Map<String, String> directives = new HashMap<String, String>(1);
+	private final Resource resource;
+	
+	public RequireBundleRequirement(RequireBundleHeader.Clause clause) {
+		this(clause, null);
+	}
+	
+	public RequireBundleRequirement(
+			RequireBundleHeader.Clause clause, Resource resource) {
+		StringBuilder builder = new StringBuilder("(&(")
+				.append(NAMESPACE).append('=')
+				.append(clause.getSymbolicName()).append(')');
+		for (Attribute attribute : clause.getAttributes())
+			attribute.appendToFilter(builder);
+		directives.put(DIRECTIVE_FILTER, builder.append(')').toString());
+		this.resource = resource;
+	}
+
+	@Override
+	public Map<String, Object> getAttributes() {
+		return Collections.emptyMap();
+	}
+
+	@Override
+	public Map<String, String> getDirectives() {
+		return Collections.unmodifiableMap(directives);
+	}
+
+	@Override
+	public String getNamespace() {
+		return NAMESPACE;
+	}
+
+	@Override
+	public Resource getResource() {
+		return 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=1294392&r1=1294391&r2=1294392&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 Mon Feb 27 23:16:45 2012
@@ -114,6 +114,10 @@ public class SubsystemManifest {
 		return (ImportPackageHeader)getHeaders().get(IMPORT_PACKAGE);
 	}
 	
+	public RequireBundleHeader getRequireBundleHeader() {
+		return (RequireBundleHeader)getHeaders().get(REQUIRE_BUNDLE);
+	}
+	
 	public RequireCapabilityHeader getRequireCapabilityHeader() {
 		return (RequireCapabilityHeader)getHeaders().get(REQUIRE_CAPABILITY);
 	}

Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/VisibilityDirective.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/VisibilityDirective.java?rev=1294392&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/VisibilityDirective.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/VisibilityDirective.java Mon Feb 27 23:16:45 2012
@@ -0,0 +1,36 @@
+package org.apache.aries.subsystem.core.archive;
+
+import org.osgi.framework.Constants;
+
+public class VisibilityDirective extends AbstractDirective {
+	public static final String NAME = Constants.VISIBILITY_DIRECTIVE;
+	public static final String VALUE_PRIVATE = Constants.VISIBILITY_PRIVATE;
+	public static final String VALUE_REEXPORT = Constants.VISIBILITY_REEXPORT;
+	
+	public static final VisibilityDirective PRIVATE = new VisibilityDirective(VALUE_PRIVATE);
+	public static final VisibilityDirective REEXPORT = new VisibilityDirective(VALUE_REEXPORT);
+	
+	public static VisibilityDirective getInstance(String value) {
+		if (VALUE_PRIVATE.equals(value))
+			return PRIVATE;
+		if (VALUE_REEXPORT.equals(value))
+			return REEXPORT;
+		return new VisibilityDirective(value);
+	}
+	
+	public VisibilityDirective() {
+		this(VALUE_PRIVATE);
+	}
+	
+	public VisibilityDirective(String value) {
+		super(NAME, value);
+	}
+	
+	public boolean isPrivate() {
+		return PRIVATE == this || VALUE_PRIVATE.equals(getValue());
+	}
+	
+	public boolean isReexport() {
+		return REEXPORT == this || VALUE_REEXPORT.equals(getValue());
+	}
+}

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=1294392&r1=1294391&r2=1294392&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 Mon Feb 27 23:16:45 2012
@@ -51,6 +51,8 @@ import org.apache.aries.subsystem.core.a
 import org.apache.aries.subsystem.core.archive.ImportPackageRequirement;
 import org.apache.aries.subsystem.core.archive.ProvisionResourceHeader;
 import org.apache.aries.subsystem.core.archive.ProvisionResourceHeader.ProvisionedResource;
+import org.apache.aries.subsystem.core.archive.RequireBundleHeader;
+import org.apache.aries.subsystem.core.archive.RequireBundleRequirement;
 import org.apache.aries.subsystem.core.archive.RequireCapabilityHeader;
 import org.apache.aries.subsystem.core.archive.RequireCapabilityRequirement;
 import org.apache.aries.subsystem.core.archive.SubsystemArchive;
@@ -1047,10 +1049,10 @@ public class AriesSubsystem implements S
 		if (isFeature())
 			// Features share the same isolation as that of their scoped parent.
 			return;
+		Region from = region;
+		Region to = ((AriesSubsystem)getParents().iterator().next()).region;
+		RegionFilterBuilder builder = from.getRegionDigraph().createRegionFilterBuilder();
 		if (isApplication() || isComposite()) {
-			Region from = region;
-			Region to = ((AriesSubsystem)getParents().iterator().next()).region;
-			RegionFilterBuilder builder = from.getRegionDigraph().createRegionFilterBuilder();
 			// Both applications and composites have Import-Package headers that require processing.
 			// In the case of applications, the header is generated.
 			Header<?> header = getDeploymentManifest().getImportPackageHeader();
@@ -1063,11 +1065,6 @@ public class AriesSubsystem implements S
 			// In the case of applications, the header is generated.
 			header = getDeploymentManifest().getSubsystemImportServiceHeader();
 			setImportIsolationPolicy(builder, (SubsystemImportServiceHeader)header);
-			RegionFilter regionFilter = builder.build();
-			if (LOGGER.isDebugEnabled())
-				LOGGER.debug("Establishing region connection: from=" + from
-						+ ", to=" + to + ", filter=" + regionFilter);
-			from.connectRegion(to, regionFilter);
 		}
 		if (isApplication()) {
 			// TODO Implement import isolation policy for applications.
@@ -1076,7 +1073,14 @@ public class AriesSubsystem implements S
 		else if (isComposite()) {
 			// TODO Implement import isolation policy for composites.
 			// Composites specify an explicit import policy in their subsystem and deployment manifests.
+			Header<?> header = getDeploymentManifest().getRequireBundleHeader();
+			setImportIsolationPolicy(builder, (RequireBundleHeader)header);
 		}
+		RegionFilter regionFilter = builder.build();
+		if (LOGGER.isDebugEnabled())
+			LOGGER.debug("Establishing region connection: from=" + from
+					+ ", to=" + to + ", filter=" + regionFilter);
+		from.connectRegion(to, regionFilter);
 	}
 	
 	private static void setImportIsolationPolicy(RegionFilterBuilder builder, ImportPackageHeader header) throws InvalidSyntaxException {
@@ -1092,6 +1096,19 @@ public class AriesSubsystem implements S
 		}
 	}
 	
+	private static void setImportIsolationPolicy(RegionFilterBuilder builder, RequireBundleHeader header) throws InvalidSyntaxException {
+		if (header == null)
+			return;
+		for (RequireBundleHeader.Clause clause : header.getClauses()) {
+			RequireBundleRequirement requirement = new RequireBundleRequirement(clause);
+			String policy = RegionFilter.VISIBLE_REQUIRE_NAMESPACE;
+			String filter = requirement.getDirectives().get(RequireBundleRequirement.DIRECTIVE_FILTER);
+			if (LOGGER.isDebugEnabled())
+				LOGGER.debug("Allowing " + policy + " of " + filter);
+			builder.allow(policy, filter);
+		}
+	}
+	
 	private static void setImportIsolationPolicy(RegionFilterBuilder builder, RequireCapabilityHeader header) throws InvalidSyntaxException {
 		if (header == null)
 			return;
@@ -1111,7 +1128,7 @@ public class AriesSubsystem implements S
 		for (SubsystemImportServiceHeader.Clause clause : header.getClauses()) {
 			SubsystemImportServiceRequirement requirement = new SubsystemImportServiceRequirement(clause);
 			String policy = RegionFilter.VISIBLE_SERVICE_NAMESPACE;
-			String filter = requirement.getDirectives().get(RequireCapabilityRequirement.DIRECTIVE_FILTER);
+			String filter = requirement.getDirectives().get(SubsystemImportServiceRequirement.DIRECTIVE_FILTER);
 			if (LOGGER.isDebugEnabled())
 				LOGGER.debug("Allowing " + policy + " of " + filter);
 			builder.allow(policy, filter);

Modified: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/CompositeTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/CompositeTest.java?rev=1294392&r1=1294391&r2=1294392&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/CompositeTest.java (original)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/CompositeTest.java Mon Feb 27 23:16:45 2012
@@ -2,8 +2,13 @@ package org.apache.aries.subsystem.itest
 
 import java.io.FileInputStream;
 import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
 
 import org.apache.aries.unittest.fixture.ArchiveFixture;
+import org.apache.aries.unittest.fixture.ArchiveFixture.JarFixture;
+import org.apache.aries.unittest.fixture.ArchiveFixture.ManifestFixture;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -15,6 +20,15 @@ import org.osgi.service.subsystem.Subsys
 
 @RunWith(JUnit4TestRunner.class)
 public class CompositeTest extends SubsystemTest {
+	private static final String BUNDLE_A = "org.apache.aries.subsystem.itests.bundle.a";
+	private static final String BUNDLE_B = "org.apache.aries.subsystem.itests.bundle.b";
+	private static final String BUNDLE_C = "org.apache.aries.subsystem.itests.bundle.c";
+	private static final String BUNDLE_D = "org.apache.aries.subsystem.itests.bundle.d";
+	private static final String BUNDLE_E = "org.apache.aries.subsystem.itests.bundle.e";
+	private static final String COMPOSITE_B = "org.apache.aries.subsystem.itests.subsystem.composite.b";
+	private static final String COMPOSITE_C = "org.apache.aries.subsystem.itests.subsystem.composite.c";
+	private static final String COMPOSITE_D = "org.apache.aries.subsystem.itests.subsystem.composite.d";
+	
 	private static boolean createdTestFiles;
 	
 	@Before
@@ -24,109 +38,129 @@ public class CompositeTest extends Subsy
 		createBundleA();
 		createBundleB();
 		createBundleC();
+		createBundleD();
 		createBundleE();
+		createCompositeB();
 		createCompositeC();
 		createCompositeD();
 		createdTestFiles = true;
 	}
 	
+	private static void createBundle(String symbolicName) throws IOException {
+		createBundle(symbolicName, null);
+	}
+	
+	private static void createBundle(String symbolicName, Map<String, String> headers) throws IOException {
+		createBundle(symbolicName, null, headers);
+	}
+	
+	private static void createBundle(String symbolicName, String version, Map<String, String> headers) throws IOException {
+		if (headers == null)
+			headers = new HashMap<String, String>();
+		headers.put(Constants.BUNDLE_SYMBOLICNAME, symbolicName);
+		if (version != null)
+			headers.put(Constants.BUNDLE_VERSION, version);
+		createBundle(headers);
+	}
+	
+	private static void createBundle(Map<String, String> headers) throws IOException {
+		String symbolicName = headers.get(Constants.BUNDLE_SYMBOLICNAME);
+		JarFixture bundle = ArchiveFixture.newJar();
+		ManifestFixture manifest = bundle.manifest();
+		for (Entry<String, String> header : headers.entrySet()) {
+			manifest.attribute(header.getKey(), header.getValue());
+		}
+		write(symbolicName, bundle);
+	}
+	
 	private static void createBundleA() throws IOException {
-		write("bundle.a.jar",
-				ArchiveFixture
-						.newJar()
-						.manifest()
-						.symbolicName(
-								"org.apache.aries.subsystem.itests.bundle.a")
-						.attribute(Constants.EXPORT_PACKAGE,
-								"org.apache.aries.subsystem.itests.bundle.a.x;version=\"1.0\"")
-						.end());
+		Map<String, String> headers = new HashMap<String, String>();
+		headers.put(Constants.EXPORT_PACKAGE, BUNDLE_A + ".x;version=\"1.0\"");
+		createBundle(BUNDLE_A, "1.0.0", headers);
 	}
 	
 	private static void createBundleB() throws IOException {
-		write("bundle.b.jar",
-				ArchiveFixture
-						.newJar()
-						.manifest()
-						.symbolicName(
-								"org.apache.aries.subsystem.itests.bundle.b")
-						.version("1.0.0")
-						.attribute(Constants.PROVIDE_CAPABILITY,
-								"y; y=test; version:Version=1.0")
-						.end());
+		Map<String, String> headers = new HashMap<String, String>();
+		headers.put(Constants.PROVIDE_CAPABILITY, "y; y=test; version:Version=1.0");
+		createBundle(BUNDLE_B, "1.0.0", headers);
 	}
 	
 	private static void createBundleC() throws IOException {
-		write("bundle.c.jar",
-				ArchiveFixture
-						.newJar()
-						.manifest()
-						.symbolicName(
-								"org.apache.aries.subsystem.itests.bundle.c")
-						.attribute(Constants.IMPORT_PACKAGE,
-								"org.apache.aries.subsystem.itests.bundle.a.x;version=\"[1.0,2.0)\"")
-						.end());
+		Map<String, String> headers = new HashMap<String, String>();
+		headers.put(Constants.IMPORT_PACKAGE, BUNDLE_A + ".x;version=\"[1.0,2.0)\"");
+		createBundle(BUNDLE_C, headers);
+	}
+	
+	private static void createBundleD() throws IOException {
+		Map<String, String> headers = new HashMap<String, String>();
+		headers.put(Constants.REQUIRE_BUNDLE, BUNDLE_A);
+		createBundle(BUNDLE_D, headers);
 	}
 	
 	private static void createBundleE() throws IOException {
-		write("bundle.e.jar",
-				ArchiveFixture
-						.newJar()
-						.manifest()
-						.symbolicName(
-								"org.apache.aries.subsystem.itests.bundle.e")
-						.version("1.0.0")
-						.attribute(Constants.REQUIRE_CAPABILITY,
-								"y; filter:=(y=test)")
-						.end());
+		Map<String, String> headers = new HashMap<String, String>();
+		headers.put(Constants.REQUIRE_CAPABILITY, "y; filter:=(y=test)");
+		createBundle(BUNDLE_E, headers);
+	}
+	
+	private static void createCompositeB() throws IOException {
+		createCompositeBManifest();
+		createSubsystem(COMPOSITE_B, "COMPOSITE.B.MF");
 	}
 	
 	private static void createCompositeC() throws IOException {
 		createCompositeCManifest();
-		write("composite.c.esa",
-				ArchiveFixture.newZip().binary("OSGI-INF/SUBSYSTEM.MF",
-						new FileInputStream("COMPOSITE.C.MF")));
+		createSubsystem(COMPOSITE_C, "COMPOSITE.C.MF");
 	}
 	
 	private static void createCompositeD() throws IOException {
 		createCompositeDManifest();
-		write("composite.d.esa",
-				ArchiveFixture.newZip().binary("OSGI-INF/SUBSYSTEM.MF",
-						new FileInputStream("COMPOSITE.D.MF")));
+		createSubsystem(COMPOSITE_D, "COMPOSITE.D.MF");
+	}
+	
+	private static void createCompositeBManifest() throws IOException {
+		Map<String, String> attributes = new HashMap<String, String>();
+		attributes.put(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME, COMPOSITE_B);
+		attributes.put(SubsystemConstants.SUBSYSTEM_TYPE, SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE);
+		attributes.put(Constants.REQUIRE_BUNDLE, BUNDLE_A + "; bundle-version=\"[1.0, 2.0)\", does.not.exist; bundle-version=\"[1.0, 2.0)\"");
+		createManifest("COMPOSITE.B.MF", attributes);
 	}
 	
 	private static void createCompositeCManifest() throws IOException {
-		write("COMPOSITE.C.MF",
-				ArchiveFixture
-						.newJar()
-						.manifest()
-						.attribute(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME,
-								"org.apache.aries.subsystem.itests.subsystem.composite.c")
-						.attribute(SubsystemConstants.SUBSYSTEM_TYPE,
-								SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE)
-						.attribute(Constants.IMPORT_PACKAGE,
-								"org.apache.aries.subsystem.itests.bundle.a.x, does.not.exist; a=b"));
+		Map<String, String> attributes = new HashMap<String, String>();
+		attributes.put(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME, COMPOSITE_C);
+		attributes.put(SubsystemConstants.SUBSYSTEM_TYPE, SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE);
+		attributes.put(Constants.IMPORT_PACKAGE, BUNDLE_A + ".x, does.not.exist; a=b");
+		createManifest("COMPOSITE.C.MF", attributes);
 	}
 	
 	private static void createCompositeDManifest() throws IOException {
-		write("COMPOSITE.D.MF",
-				ArchiveFixture
-						.newJar()
-						.manifest()
-						.attribute(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME,
-								"org.apache.aries.subsystem.itests.subsystem.composite.d")
-						.attribute(SubsystemConstants.SUBSYSTEM_TYPE,
-								SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE)
-						.attribute(Constants.REQUIRE_CAPABILITY,
-								"y; filter:=\"(y=test)\", does.not.exist; filter:=\"(a=b)\""));
+		Map<String, String> attributes = new HashMap<String, String>();
+		attributes.put(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME, COMPOSITE_D);
+		attributes.put(SubsystemConstants.SUBSYSTEM_TYPE, SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE);
+		attributes.put(Constants.REQUIRE_CAPABILITY, "y; filter:=\"(y=test)\", does.not.exist; filter:=\"(a=b)\"");
+		createManifest("COMPOSITE.D.MF", attributes);
+	}
+	
+	private static void createManifest(String name, Map<String, String> headers) throws IOException {
+		ManifestFixture manifest = ArchiveFixture.newJar().manifest();
+		for (Entry<String, String> header : headers.entrySet()) {
+			manifest.attribute(header.getKey(), header.getValue());
+		}
+		write(name, manifest);
+	}
+	
+	private static void createSubsystem(String name, String manifest) throws IOException {
+		write(name, ArchiveFixture.newZip().binary("OSGI-INF/SUBSYSTEM.MF", new FileInputStream(manifest)));
 	}
 	
 	@Test
 	public void testImportPackage() throws Exception {
-		Bundle bundleA = installBundleFromFile("bundle.a.jar");
+		Bundle bundleA = installBundleFromFile(BUNDLE_A);
 		try {
-			Subsystem compositeC = installSubsystemFromFile("composite.c.esa");
+			Subsystem compositeC = installSubsystemFromFile(COMPOSITE_C);
 			try {
-				Bundle bundleC = installBundleFromFile("bundle.c.jar", compositeC);
+				Bundle bundleC = installBundleFromFile(BUNDLE_C, compositeC);
 				try {
 					startBundle(bundleC, compositeC);
 				}
@@ -144,12 +178,35 @@ public class CompositeTest extends Subsy
 	}
 	
 	@Test
+	public void testRequireBundle() throws Exception {
+		Bundle bundleA = installBundleFromFile(BUNDLE_A);
+		try {
+			Subsystem compositeB = installSubsystemFromFile(COMPOSITE_B);
+			try {
+				Bundle bundleD = installBundleFromFile(BUNDLE_D, compositeB);
+				try {
+					startBundle(bundleD, compositeB);
+				}
+				finally {
+					bundleD.uninstall();
+				}
+			}
+			finally {
+				uninstallScopedSubsystem(compositeB);
+			}
+		}
+		finally {
+			bundleA.uninstall();
+		}
+	}
+	
+	@Test
 	public void testRequireCapability() throws Exception {
-		Bundle bundleB = installBundleFromFile("bundle.b.jar");
+		Bundle bundleB = installBundleFromFile(BUNDLE_B);
 		try {
-			Subsystem compositeD = installSubsystemFromFile("composite.d.esa");
+			Subsystem compositeD = installSubsystemFromFile(COMPOSITE_D);
 			try {
-				Bundle bundleE = installBundleFromFile("bundle.e.jar", compositeD);
+				Bundle bundleE = installBundleFromFile(BUNDLE_E, compositeD);
 				try {
 					startBundle(bundleE, compositeD);
 				}