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 18:17:25 UTC

svn commit: r1294738 - 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: Tue Feb 28 17:17:24 2012
New Revision: 1294738

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

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

Added:
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ExportPackageCapability.java
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/ExportPackageHeader.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/SubsystemManifest.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/VersionAttribute.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/resource/BundleResource.java
    aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/CompositeTest.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/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=1294738&r1=1294737&r2=1294738&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 Tue Feb 28 17:17:24 2012
@@ -130,6 +130,9 @@ public class DeploymentManifest {
 				header = subsystemManifest.getRequireBundleHeader();
 				if (header != null)
 					headers.put(REQUIRE_BUNDLE, header);
+				header = subsystemManifest.getExportPackageHeader();
+				if (header != null)
+					headers.put(EXPORT_PACKAGE, header);
 				// TODO Compute additional headers for a composite. 
 			}
 			// Features require no additional headers.
@@ -149,6 +152,10 @@ public class DeploymentManifest {
 		return (DeployedContentHeader)getHeaders().get(DEPLOYED_CONTENT);
 	}
 	
+	public ExportPackageHeader getExportPackageHeader() {
+		return (ExportPackageHeader)getHeaders().get(EXPORT_PACKAGE);
+	}
+	
 	public Map<String, Header<?>> getHeaders() {
 		return headers;
 	}

Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ExportPackageCapability.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ExportPackageCapability.java?rev=1294738&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ExportPackageCapability.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ExportPackageCapability.java Tue Feb 28 17:17:24 2012
@@ -0,0 +1,49 @@
+package org.apache.aries.subsystem.core.archive;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.aries.subsystem.core.resource.AbstractCapability;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.resource.Resource;
+
+public class ExportPackageCapability extends AbstractCapability {
+	public static final String NAMESPACE = PackageNamespace.PACKAGE_NAMESPACE;
+	
+	private final Map<String, Object> attributes = new HashMap<String, Object>();
+	private final Map<String, String> directives = new HashMap<String, String>();
+	private final Resource resource;
+	
+	public ExportPackageCapability(String packageName, Collection<Parameter> parameters, Resource resource) {
+		attributes.put(NAMESPACE, packageName);
+		for (Parameter parameter : parameters) {
+			if (parameter instanceof Attribute)
+				attributes.put(parameter.getName(), parameter.getValue());
+			else
+				directives.put(parameter.getName(), parameter.getValue());
+		}
+		this.resource = resource;
+	}
+
+	@Override
+	public Map<String, Object> getAttributes() {
+		return Collections.unmodifiableMap(attributes);
+	}
+
+	@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/ExportPackageHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ExportPackageHeader.java?rev=1294738&r1=1294737&r2=1294738&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ExportPackageHeader.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ExportPackageHeader.java Tue Feb 28 17:17:24 2012
@@ -15,65 +15,178 @@ package org.apache.aries.subsystem.core.
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
-import java.util.List;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
-import org.apache.aries.subsystem.core.resource.AbstractCapability;
 import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
-import org.osgi.framework.namespace.PackageNamespace;
-import org.osgi.resource.Capability;
 import org.osgi.resource.Resource;
 
-public class ExportPackageHeader extends AbstractHeader {
+public class ExportPackageHeader implements Header<ExportPackageHeader.Clause> {
+	public static class Clause implements org.apache.aries.subsystem.core.archive.Clause {
+		public static final String ATTRIBUTE_VERSION = Constants.VERSION_ATTRIBUTE;
+		public static final String DIRECTIVE_EXCLUDE = Constants.EXCLUDE_DIRECTIVE;
+		public static final String DIRECTIVE_INCLUDE = Constants.INCLUDE_DIRECTIVE;
+		public static final String DIRECTIVE_MANDATORY = Constants.MANDATORY_DIRECTIVE;
+		public static final String DIRECTIVE_USES = Constants.USES_DIRECTIVE;
+		
+		private static final Pattern PATTERN_PACKAGENAME = Pattern.compile('(' + Grammar.PACKAGENAME + ")(?=;|\\z)");
+		private static final Pattern PATTERN_PACKAGENAMES = Pattern.compile('(' + Grammar.PACKAGENAMES + ")(?=;|\\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);
+		}
+		
+		private final Collection<String> packageNames = new HashSet<String>();
+		private final String path;
+		private final Map<String, Parameter> parameters = new HashMap<String, Parameter>();
+		
+		public Clause(String clause) {
+			Matcher main = PATTERN_PACKAGENAMES.matcher(clause);
+			if (!main.find())
+				throw new IllegalArgumentException("Missing package names path: " + clause);
+			path = main.group();
+			Matcher path = PATTERN_PACKAGENAME.matcher(this.path);
+			while (path.find())
+				packageNames.add(main.group());
+			main.usePattern(PATTERN_PARAMETER);
+			while (main.find()) {
+				Parameter parameter = ParameterFactory.create(main.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;
+		}
+		
+		public Collection<String> getPackageNames() {
+			return Collections.unmodifiableCollection(packageNames);
+		}
+
+		@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 Collection<ExportPackageCapability> toCapabilities(Resource resource) {
+			Collection<ExportPackageCapability> result = new ArrayList<ExportPackageCapability>(packageNames.size());
+			for (String packageName : packageNames)
+				result.add(new ExportPackageCapability(packageName, parameters.values(), resource));
+			return result;
+		}
+		
+		@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.EXPORT_PACKAGE;
 	
+	private static final Pattern PATTERN = Pattern.compile('(' + Grammar.EXPORT + ")(?=,|\\z)");
+	
+	private final Set<Clause> clauses = new HashSet<Clause>();
+	
 	public ExportPackageHeader(String value) {
-		super(NAME, value);
+		Matcher matcher = PATTERN.matcher(value);
+		while (matcher.find())
+			clauses.add(new Clause(matcher.group()));
+		if (clauses.isEmpty())
+			throw new IllegalArgumentException("An " + NAME + " header must have at least one clause");
 	}
 	
-	public List<Capability> getCapabilities(final Resource resource) {
-		List<Capability> capabilities = new ArrayList<Capability>(clauses.size());
-		for (final Clause clause : clauses) {
-			String[] exportedPackages = clause.getPath().split(";");
-			for (final String exportedPackage : exportedPackages) {
-				capabilities.add(new AbstractCapability() {
-					@Override
-					public String getNamespace() {
-						return PackageNamespace.PACKAGE_NAMESPACE;
-					}
-
-					@Override
-					public Map<String, String> getDirectives() {
-						Collection<Directive> directives = clause.getDirectives();
-						Map<String, String> result = new HashMap<String, String>(directives.size());
-						for (Directive directive : directives)
-							result.put(directive.getName(), directive.getValue());
-						return result;
-					}
-
-					@Override
-					public Map<String, Object> getAttributes() {
-						Collection<Attribute> attributes = clause.getAttributes();
-						Map<String, Object> result = new HashMap<String, Object>(attributes.size() + 1);
-						for (Attribute attribute : attributes)
-							result.put(attribute.getName(), attribute.getValue());
-						// Add the namespace attribute.
-						result.put(PackageNamespace.PACKAGE_NAMESPACE, exportedPackage);
-						// Add the default version, if necessary.
-						if (result.get(Constants.VERSION_ATTRIBUTE) == null)
-							result.put(Constants.VERSION_ATTRIBUTE, Version.emptyVersion);
-						return result;
-					}
-
-					@Override
-					public Resource getResource() {
-						return resource;
-					}
-				});
-			}
+	@Override
+	public Collection<ExportPackageHeader.Clause> getClauses() {
+		return Collections.unmodifiableSet(clauses);
+	}
+
+	@Override
+	public String getName() {
+		return NAME;
+	}
+
+	@Override
+	public String getValue() {
+		return toString();
+	}
+	
+	public Collection<ExportPackageCapability> toCapabilities(Resource resource) {
+		Collection<ExportPackageCapability> result = new ArrayList<ExportPackageCapability>();
+		for (Clause clause : clauses)
+			result.addAll(clause.toCapabilities(resource));
+		return result;
+	}
+	
+	@Override
+	public String toString() {
+		StringBuilder builder = new StringBuilder();
+		for (Clause clause : getClauses()) {
+			builder.append(clause).append(',');
 		}
-		return capabilities;
+		// 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/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=1294738&r1=1294737&r2=1294738&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 Tue Feb 28 17:17:24 2012
@@ -122,6 +122,9 @@ public interface Grammar {
 	public static final String BUNDLE_DESCRIPTION = SYMBOLICNAME + "(?:;\\s*(?:" + PARAMETER + "))*";
 	public static final String REQUIRE_BUNDLE = BUNDLE_DESCRIPTION + "(?:,\\s*(?:" + BUNDLE_DESCRIPTION + "))*";
 	
+	public static final String EXPORT = PACKAGENAMES + "(?:;\\s*(?:" + PARAMETER + "))*";
+	public static final String EXPORT_PACKAGE = EXPORT + "(?:,\\s*(?:" + EXPORT + "))*";
+	
 	/*
 	 * number ::= digit+
 	 * version ::= major( '.' minor ( '.' micro ( '.' qualifier )? )? )?

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=1294738&r1=1294737&r2=1294738&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 Tue Feb 28 17:17:24 2012
@@ -110,6 +110,10 @@ public class SubsystemManifest {
 		return headers;
 	}
 	
+	public ExportPackageHeader getExportPackageHeader() {
+		return (ExportPackageHeader)getHeaders().get(EXPORT_PACKAGE);
+	}
+	
 	public ImportPackageHeader getImportPackageHeader() {
 		return (ImportPackageHeader)getHeaders().get(IMPORT_PACKAGE);
 	}

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/VersionAttribute.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/VersionAttribute.java?rev=1294738&r1=1294737&r2=1294738&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/VersionAttribute.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/VersionAttribute.java Tue Feb 28 17:17:24 2012
@@ -19,11 +19,12 @@ import org.osgi.framework.Version;
 public class VersionAttribute extends AbstractAttribute {
 	public static final String NAME = Constants.VERSION_ATTRIBUTE;
 	
+	public static final VersionAttribute DEFAULT = new VersionAttribute();
+	
 	private final Version version;
 	
 	public VersionAttribute() {
-		super(NAME, Version.emptyVersion.toString());
-		version = Version.emptyVersion;
+		this(Version.emptyVersion.toString());
 	}
 	
 	public VersionAttribute(String value) {

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=1294738&r1=1294737&r2=1294738&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 Tue Feb 28 17:17:24 2012
@@ -46,6 +46,8 @@ import org.apache.aries.subsystem.core.R
 import org.apache.aries.subsystem.core.archive.DeployedContentHeader;
 import org.apache.aries.subsystem.core.archive.DeployedContentHeader.DeployedContent;
 import org.apache.aries.subsystem.core.archive.DeploymentManifest;
+import org.apache.aries.subsystem.core.archive.ExportPackageCapability;
+import org.apache.aries.subsystem.core.archive.ExportPackageHeader;
 import org.apache.aries.subsystem.core.archive.Header;
 import org.apache.aries.subsystem.core.archive.ImportPackageHeader;
 import org.apache.aries.subsystem.core.archive.ImportPackageRequirement;
@@ -1035,11 +1037,40 @@ public class AriesSubsystem implements S
 		}
 	}
 	
-	private void setExportIsolationPolicy() {
-		// Archive is null for root subsystem.
-		if (archive == null)
+	private void setExportIsolationPolicy() throws InvalidSyntaxException, IOException, BundleException {
+		if (isRoot())
+			// Nothing to do if this is the root subsystem.
+			return;
+		if (isFeature())
+			// Features share the same isolation as that of their scoped parent.
+			return;
+		Region from = ((AriesSubsystem)getParents().iterator().next()).region;
+		Region to = region;
+		RegionFilterBuilder builder = from.getRegionDigraph().createRegionFilterBuilder();
+		if (isComposite()) {
+			setExportIsolationPolicy(builder, getDeploymentManifest().getExportPackageHeader());
+			// TODO Implement export isolation policy for composites.
+		}
+		RegionFilter regionFilter = builder.build();
+		if (LOGGER.isDebugEnabled())
+			LOGGER.debug("Establishing region connection: from=" + from
+					+ ", to=" + to + ", filter=" + regionFilter);
+		from.connectRegion(to, regionFilter);
+	}
+	
+	private void setExportIsolationPolicy(RegionFilterBuilder builder, ExportPackageHeader header) throws InvalidSyntaxException {
+		if (header == null)
 			return;
-		// TODO Implement export isolation policy for composites.
+		String policy = RegionFilter.VISIBLE_PACKAGE_NAMESPACE;
+		for (ExportPackageCapability capability : header.toCapabilities(this)) {
+			StringBuilder filter = new StringBuilder("(&");
+			for (Entry<String, Object> attribute : capability.getAttributes().entrySet())
+				filter.append('(').append(attribute.getKey()).append('=').append(attribute.getValue()).append(')');
+			filter.append(')');
+			if (LOGGER.isDebugEnabled())
+				LOGGER.debug("Allowing " + policy + " of " + filter);
+			builder.allow(policy, filter.toString());
+		}
 	}
 
 	private void setImportIsolationPolicy() throws BundleException, IOException, InvalidSyntaxException {

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/BundleResource.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/BundleResource.java?rev=1294738&r1=1294737&r2=1294738&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/BundleResource.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/BundleResource.java Tue Feb 28 17:17:24 2012
@@ -59,7 +59,7 @@ public class BundleResource implements R
 		}
 		ExportPackageHeader eph = (ExportPackageHeader)manifest.getHeader(ExportPackageHeader.NAME);
 		if (eph != null) {
-			capabilities.addAll(eph.getCapabilities(this));
+			capabilities.addAll(eph.toCapabilities(this));
 		}
 		ImportPackageHeader iph = (ImportPackageHeader)manifest.getHeader(ImportPackageHeader.NAME);
 		if (iph != null) {

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=1294738&r1=1294737&r2=1294738&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 Tue Feb 28 17:17:24 2012
@@ -20,14 +20,16 @@ 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 final String BUNDLE_A = "bundle.a";
+	private static final String BUNDLE_B = "bundle.b";
+	private static final String BUNDLE_C = "bundle.c";
+	private static final String BUNDLE_D = "bundle.d";
+	private static final String BUNDLE_E = "bundle.e";
+	private static final String COMPOSITE_A = "composite.a";
+	private static final String COMPOSITE_B = "composite.b";
+	private static final String COMPOSITE_C = "composite.c";
+	private static final String COMPOSITE_D = "composite.d";
+	private static final String PACKAGE_X = "x";
 	
 	private static boolean createdTestFiles;
 	
@@ -40,6 +42,7 @@ public class CompositeTest extends Subsy
 		createBundleC();
 		createBundleD();
 		createBundleE();
+		createCompositeA();
 		createCompositeB();
 		createCompositeC();
 		createCompositeD();
@@ -75,7 +78,7 @@ public class CompositeTest extends Subsy
 	
 	private static void createBundleA() throws IOException {
 		Map<String, String> headers = new HashMap<String, String>();
-		headers.put(Constants.EXPORT_PACKAGE, BUNDLE_A + ".x;version=\"1.0\"");
+		headers.put(Constants.EXPORT_PACKAGE, PACKAGE_X + ";version=1.0");
 		createBundle(BUNDLE_A, "1.0.0", headers);
 	}
 	
@@ -87,8 +90,8 @@ public class CompositeTest extends Subsy
 	
 	private static void createBundleC() throws IOException {
 		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);
+		headers.put(Constants.IMPORT_PACKAGE, PACKAGE_X + ";version=\"[1.0,2.0)\"");
+		createBundle(BUNDLE_C, "1.0.0", headers);
 	}
 	
 	private static void createBundleD() throws IOException {
@@ -103,19 +106,32 @@ public class CompositeTest extends Subsy
 		createBundle(BUNDLE_E, headers);
 	}
 	
+	private static void createCompositeA() throws IOException {
+		createCompositeAManifest();
+		createSubsystem(COMPOSITE_A);
+	}
+	
 	private static void createCompositeB() throws IOException {
 		createCompositeBManifest();
-		createSubsystem(COMPOSITE_B, "COMPOSITE.B.MF");
+		createSubsystem(COMPOSITE_B);
 	}
 	
 	private static void createCompositeC() throws IOException {
 		createCompositeCManifest();
-		createSubsystem(COMPOSITE_C, "COMPOSITE.C.MF");
+		createSubsystem(COMPOSITE_C);
 	}
 	
 	private static void createCompositeD() throws IOException {
 		createCompositeDManifest();
-		createSubsystem(COMPOSITE_D, "COMPOSITE.D.MF");
+		createSubsystem(COMPOSITE_D);
+	}
+	
+	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.EXPORT_PACKAGE, PACKAGE_X + "; version=1.0, does.not.exist; a=b");
+		createManifest(COMPOSITE_A + ".mf", attributes);
 	}
 	
 	private static void createCompositeBManifest() throws IOException {
@@ -123,15 +139,15 @@ public class CompositeTest extends Subsy
 		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);
+		createManifest(COMPOSITE_B + ".mf", attributes);
 	}
 	
 	private static void createCompositeCManifest() throws IOException {
 		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);
+		attributes.put(Constants.IMPORT_PACKAGE, PACKAGE_X + ", does.not.exist; a=b");
+		createManifest(COMPOSITE_C + ".mf", attributes);
 	}
 	
 	private static void createCompositeDManifest() throws IOException {
@@ -139,7 +155,7 @@ public class CompositeTest extends Subsy
 		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);
+		createManifest(COMPOSITE_D + ".mf", attributes);
 	}
 	
 	private static void createManifest(String name, Map<String, String> headers) throws IOException {
@@ -150,8 +166,33 @@ public class CompositeTest extends Subsy
 		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)));
+	private static void createSubsystem(String name) throws IOException {
+		write(name, ArchiveFixture.newZip().binary("OSGI-INF/SUBSYSTEM.MF", new FileInputStream(name + ".mf")));
+	}
+	
+	@Test
+	public void testExportPackage() throws Exception {
+		Subsystem composite = installSubsystemFromFile(COMPOSITE_A);
+		try {
+			startSubsystem(composite);
+			Bundle bundleA = installBundleFromFile(BUNDLE_A, composite);
+			try {
+				Bundle bundleC = installBundleFromFile(BUNDLE_C);
+				try {
+					startBundle(bundleC);
+				}
+				finally {
+					bundleC.uninstall();
+				}
+			}
+			finally {
+				bundleA.uninstall();
+			}
+		}
+		finally {
+			stopSubsystem(composite);
+			uninstallScopedSubsystem(composite);
+		}
 	}
 	
 	@Test

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=1294738&r1=1294737&r2=1294738&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 Tue Feb 28 17:17:24 2012
@@ -372,7 +372,7 @@ public abstract class SubsystemTest exte
 	}
 	
 	protected void assertState(EnumSet<State> expected, State actual) {
-		assertTrue("Wrong state: " + actual, expected.contains(actual));
+		assertTrue("Wrong state: expected=" + expected + ", actual=" + actual, expected.contains(actual));
 	}
 	
 	protected void assertState(State expected, Subsystem subsystem) {