You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by jw...@apache.org on 2012/03/19 00:49:35 UTC

svn commit: r1302250 - 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: Sun Mar 18 23:49:34 2012
New Revision: 1302250

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

Added initial support for tracking reference and active use count for resources so that transitive dependencies provisioned into subsystems other than the one undergoing the life cycle change are affected as well.

Added:
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/CapabilityHeader.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequirementHeader.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceReferences.java
    aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/DependencyLifeCycleTest.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/ImportPackageHeader.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ProvideCapabilityHeader.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/RequireCapabilityHeader.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemExportServiceHeader.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemImportServiceHeader.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-core/src/main/java/org/apache/aries/subsystem/core/resource/BundleResource.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemStreamResource.java
    aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java

Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/CapabilityHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/CapabilityHeader.java?rev=1302250&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/CapabilityHeader.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/CapabilityHeader.java Sun Mar 18 23:49:34 2012
@@ -0,0 +1,10 @@
+package org.apache.aries.subsystem.core.archive;
+
+import java.util.List;
+
+import org.osgi.resource.Capability;
+import org.osgi.resource.Resource;
+
+public interface CapabilityHeader<C extends Clause> extends Header<C> {
+	List<? extends Capability> toCapabilities(Resource resource);
+}

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=1302250&r1=1302249&r2=1302250&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 Sun Mar 18 23:49:34 2012
@@ -95,7 +95,6 @@ public class DeploymentManifest {
 				}
 				// TODO This does not validate that all content bundles were found.
 				resolution = Activator.getInstance().getResolver().resolve(environment, new ArrayList<Resource>(resources), Collections.EMPTY_LIST);
-				// TODO Once we have a resolver that actually returns lists of wires, we can use them to compute other manifest headers such as Import-Package.
 				Collection<Resource> provisionResource = new HashSet<Resource>();
 				for (Resource resource : resolution.keySet()) {
 					if (contentHeader.contains(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=1302250&r1=1302249&r2=1302250&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 Sun Mar 18 23:49:34 2012
@@ -18,6 +18,7 @@ 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;
@@ -26,7 +27,7 @@ import java.util.regex.Pattern;
 import org.osgi.framework.Constants;
 import org.osgi.resource.Resource;
 
-public class ExportPackageHeader implements Header<ExportPackageHeader.Clause> {
+public class ExportPackageHeader implements CapabilityHeader<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;
@@ -172,8 +173,9 @@ public class ExportPackageHeader impleme
 		return toString();
 	}
 	
-	public Collection<ExportPackageCapability> toCapabilities(Resource resource) {
-		Collection<ExportPackageCapability> result = new ArrayList<ExportPackageCapability>();
+	@Override
+	public List<ExportPackageCapability> toCapabilities(Resource resource) {
+		List<ExportPackageCapability> result = new ArrayList<ExportPackageCapability>();
 		for (Clause clause : clauses)
 			result.addAll(clause.toCapabilities(resource));
 		return result;

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ImportPackageHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ImportPackageHeader.java?rev=1302250&r1=1302249&r2=1302250&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ImportPackageHeader.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ImportPackageHeader.java Sun Mar 18 23:49:34 2012
@@ -19,6 +19,7 @@ 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;
@@ -29,7 +30,7 @@ import org.osgi.framework.namespace.Pack
 import org.osgi.resource.Requirement;
 import org.osgi.resource.Resource;
 
-public class ImportPackageHeader implements Header<ImportPackageHeader.Clause> {
+public class ImportPackageHeader implements RequirementHeader<ImportPackageHeader.Clause> {
 	public static class Clause implements org.apache.aries.subsystem.core.archive.Clause {
 		private static final String REGEX = "\\((" + PackageNamespace.PACKAGE_NAMESPACE + ")(=)([^\\)]+)\\)";
 		private static final String REGEX1 = '(' + Grammar.PACKAGENAMES + ")(?=;|\\z)";
@@ -144,14 +145,14 @@ public class ImportPackageHeader impleme
 			return myPath;
 		}
 		
-		public Requirement getRequirement(final Resource resource) {
-			return new ImportPackageRequirement(this, resource);
-		}
-		
 		public VersionRangeAttribute getVersionRangeAttribute() {
 			return (VersionRangeAttribute)myParameters.get(Constants.VERSION_ATTRIBUTE);
 		}
 		
+		public ImportPackageRequirement toRequirement(Resource resource) {
+			return new ImportPackageRequirement(this, resource);
+		}
+		
 		@Override
 		public String toString() {
 			StringBuilder builder = new StringBuilder()
@@ -202,21 +203,22 @@ public class ImportPackageHeader impleme
 		return Constants.IMPORT_PACKAGE;
 	}
 	
-	public Collection<Requirement> getRequirements(Resource resource) {
+	@Override
+	public String getValue() {
+		return toString();
+	}
+	
+	@Override
+	public List<ImportPackageRequirement> toRequirements(Resource resource) {
 		Collection<Clause> clauses = getClauses();
-		Collection<Requirement> result = new HashSet<Requirement>(clauses.size());
+		List<ImportPackageRequirement> result = new ArrayList<ImportPackageRequirement>(clauses.size());
 		for (Clause clause : clauses) {
-			result.add(clause.getRequirement(resource));
+			result.add(clause.toRequirement(resource));
 		}
 		return result;
 	}
 	
 	@Override
-	public String getValue() {
-		return toString();
-	}
-	
-	@Override
 	public String toString() {
 		StringBuilder builder = new StringBuilder();
 		for (Clause clause : getClauses()) {

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ProvideCapabilityHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ProvideCapabilityHeader.java?rev=1302250&r1=1302249&r2=1302250&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ProvideCapabilityHeader.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ProvideCapabilityHeader.java Sun Mar 18 23:49:34 2012
@@ -18,14 +18,16 @@ 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.osgi.framework.Constants;
+import org.osgi.resource.Resource;
 
-public class ProvideCapabilityHeader implements Header<ProvideCapabilityHeader.Clause> {	
+public class ProvideCapabilityHeader implements CapabilityHeader<ProvideCapabilityHeader.Clause> {	
 	public static class Clause implements org.apache.aries.subsystem.core.archive.Clause {
 		public static final String DIRECTIVE_EFFECTIVE = Constants.EFFECTIVE_DIRECTIVE;
 		public static final String DIRECTIVE_USES = Constants.USES_DIRECTIVE;
@@ -126,6 +128,10 @@ public class ProvideCapabilityHeader imp
 			return path;
 		}
 		
+		public ProvideCapabilityCapability toCapability(Resource resource) {
+			return new ProvideCapabilityCapability(this, resource);
+		}
+		
 		@Override
 		public String toString() {
 			StringBuilder builder = new StringBuilder()
@@ -167,6 +173,14 @@ public class ProvideCapabilityHeader imp
 	}
 	
 	@Override
+	public List<ProvideCapabilityCapability> toCapabilities(Resource resource) {
+		List<ProvideCapabilityCapability> result = new ArrayList<ProvideCapabilityCapability>();
+		for (Clause clause : clauses)
+			result.add(clause.toCapability(resource));
+		return result;
+	}
+	
+	@Override
 	public String toString() {
 		StringBuilder builder = new StringBuilder();
 		for (Clause clause : getClauses()) {

Modified: 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=1302250&r1=1302249&r2=1302250&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireBundleHeader.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireBundleHeader.java Sun Mar 18 23:49:34 2012
@@ -5,6 +5,7 @@ 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;
@@ -12,8 +13,9 @@ import java.util.regex.Pattern;
 
 import org.osgi.framework.Constants;
 import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
 
-public class RequireBundleHeader implements Header<RequireBundleHeader.Clause> {
+public class RequireBundleHeader implements RequirementHeader<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;
@@ -133,6 +135,10 @@ public class RequireBundleHeader impleme
 			return path;
 		}
 		
+		public RequireBundleRequirement toRequirement() {
+			return new RequireBundleRequirement(this);
+		}
+		
 		@Override
 		public String toString() {
 			StringBuilder builder = new StringBuilder()
@@ -184,6 +190,14 @@ public class RequireBundleHeader impleme
 	}
 	
 	@Override
+	public List<RequireBundleRequirement> toRequirements(Resource resource) {
+		List<RequireBundleRequirement> requirements = new ArrayList<RequireBundleRequirement>(clauses.size());
+		for (Clause clause : clauses)
+			requirements.add(clause.toRequirement());
+		return requirements;
+	}
+	
+	@Override
 	public String toString() {
 		StringBuilder builder = new StringBuilder();
 		for (Clause clause : getClauses()) {

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireCapabilityHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireCapabilityHeader.java?rev=1302250&r1=1302249&r2=1302250&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireCapabilityHeader.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireCapabilityHeader.java Sun Mar 18 23:49:34 2012
@@ -5,6 +5,7 @@ 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.Map.Entry;
 import java.util.Set;
@@ -13,8 +14,9 @@ import java.util.regex.Pattern;
 
 import org.osgi.framework.Constants;
 import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
 
-public class RequireCapabilityHeader implements Header<RequireCapabilityHeader.Clause> {
+public class RequireCapabilityHeader implements RequirementHeader<RequireCapabilityHeader.Clause> {
 	public static class Clause implements org.apache.aries.subsystem.core.archive.Clause {
 		public static final String DIRECTIVE_EFFECTIVE = Constants.EFFECTIVE_DIRECTIVE;
 		public static final String DIRECTIVE_FILTER = Constants.FILTER_DIRECTIVE;
@@ -115,6 +117,10 @@ public class RequireCapabilityHeader imp
 			return getNamespace();
 		}
 		
+		public RequireCapabilityRequirement toRequirement() {
+			return new RequireCapabilityRequirement(this);
+		}
+		
 		@Override
 		public String toString() {
 			StringBuilder builder = new StringBuilder()
@@ -166,6 +172,14 @@ public class RequireCapabilityHeader imp
 	}
 	
 	@Override
+	public List<RequireCapabilityRequirement> toRequirements(Resource resource) {
+		List<RequireCapabilityRequirement> requirements = new ArrayList<RequireCapabilityRequirement>(clauses.size());
+		for (Clause clause : clauses)
+			requirements.add(clause.toRequirement());
+		return requirements;
+	}
+	
+	@Override
 	public String toString() {
 		StringBuilder builder = new StringBuilder();
 		for (Clause clause : getClauses()) {

Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequirementHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequirementHeader.java?rev=1302250&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequirementHeader.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequirementHeader.java Sun Mar 18 23:49:34 2012
@@ -0,0 +1,10 @@
+package org.apache.aries.subsystem.core.archive;
+
+import java.util.List;
+
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+
+public interface RequirementHeader<C extends Clause> extends Header<C> {
+	List<? extends Requirement> toRequirements(Resource resource);
+}

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemExportServiceHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemExportServiceHeader.java?rev=1302250&r1=1302249&r2=1302250&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemExportServiceHeader.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemExportServiceHeader.java Sun Mar 18 23:49:34 2012
@@ -18,15 +18,17 @@ 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.osgi.framework.Constants;
+import org.osgi.resource.Resource;
 import org.osgi.service.subsystem.SubsystemConstants;
 
-public class SubsystemExportServiceHeader implements Header<SubsystemExportServiceHeader.Clause> {
+public class SubsystemExportServiceHeader implements CapabilityHeader<SubsystemExportServiceHeader.Clause> {
 	public static class Clause implements org.apache.aries.subsystem.core.archive.Clause {
 		public static final String DIRECTIVE_FILTER = Constants.FILTER_DIRECTIVE;
 		
@@ -114,6 +116,10 @@ public class SubsystemExportServiceHeade
 			return path;
 		}
 		
+		public SubsystemExportServiceCapability toCapability(Resource resource) {
+			return new SubsystemExportServiceCapability(this, resource);
+		}
+		
 		@Override
 		public String toString() {
 			StringBuilder builder = new StringBuilder()
@@ -155,6 +161,14 @@ public class SubsystemExportServiceHeade
 	}
 	
 	@Override
+	public List<SubsystemExportServiceCapability> toCapabilities(Resource resource) {
+		List<SubsystemExportServiceCapability> result = new ArrayList<SubsystemExportServiceCapability>();
+		for (Clause clause : clauses)
+			result.add(clause.toCapability(resource));
+		return result;
+	}
+	
+	@Override
 	public String toString() {
 		StringBuilder builder = new StringBuilder();
 		for (Clause clause : getClauses()) {

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemImportServiceHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemImportServiceHeader.java?rev=1302250&r1=1302249&r2=1302250&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemImportServiceHeader.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemImportServiceHeader.java Sun Mar 18 23:49:34 2012
@@ -5,15 +5,17 @@ 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.osgi.framework.Constants;
+import org.osgi.resource.Resource;
 import org.osgi.service.subsystem.SubsystemConstants;
 
-public class SubsystemImportServiceHeader implements Header<SubsystemImportServiceHeader.Clause> {
+public class SubsystemImportServiceHeader implements RequirementHeader<SubsystemImportServiceHeader.Clause> {
 	public static class Clause implements org.apache.aries.subsystem.core.archive.Clause {
 		public static final String DIRECTIVE_EFFECTIVE = Constants.EFFECTIVE_DIRECTIVE;
 		public static final String DIRECTIVE_FILTER = Constants.FILTER_DIRECTIVE;
@@ -108,6 +110,10 @@ public class SubsystemImportServiceHeade
 			return path;
 		}
 		
+		public SubsystemImportServiceRequirement toRequirement() {
+			return new SubsystemImportServiceRequirement(this);
+		}
+		
 		@Override
 		public String toString() {
 			StringBuilder builder = new StringBuilder()
@@ -150,6 +156,14 @@ public class SubsystemImportServiceHeade
 	}
 	
 	@Override
+	public List<SubsystemImportServiceRequirement> toRequirements(Resource resource) {
+		List<SubsystemImportServiceRequirement> requirements = new ArrayList<SubsystemImportServiceRequirement>(clauses.size());
+		for (Clause clause : clauses)
+			requirements.add(clause.toRequirement());
+		return requirements;
+	}
+	
+	@Override
 	public String toString() {
 		StringBuilder builder = new StringBuilder();
 		for (Clause clause : getClauses()) {

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=1302250&r1=1302249&r2=1302250&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 Sun Mar 18 23:49:34 2012
@@ -5,9 +5,11 @@ import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.jar.Attributes;
@@ -16,6 +18,8 @@ import java.util.jar.Manifest;
 import org.apache.aries.util.manifest.ManifestProcessor;
 import org.osgi.framework.Constants;
 import org.osgi.framework.Version;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
 import org.osgi.resource.Resource;
 import org.osgi.service.subsystem.SubsystemConstants;
 
@@ -191,6 +195,24 @@ public class SubsystemManifest {
 		return (SubsystemVersionHeader)getHeaders().get(SUBSYSTEM_VERSION);
 	}
 	
+	public List<Capability> toCapabilities(Resource resource) {
+		ArrayList<Capability> requirements = new ArrayList<Capability>();
+		for (Header<?> header : headers.values())
+			if (header instanceof CapabilityHeader)
+				requirements.addAll(((CapabilityHeader<?>)header).toCapabilities(resource));
+		requirements.trimToSize();
+		return requirements;
+	}
+	
+	public List<Requirement> toRequirements(Resource resource) {
+		ArrayList<Requirement> requirements = new ArrayList<Requirement>();
+		for (Header<?> header : headers.values())
+			if (header instanceof RequirementHeader)
+				requirements.addAll(((RequirementHeader<?>)header).toRequirements(resource));
+		requirements.trimToSize();
+		return requirements;
+	}
+	
 	public void write(OutputStream out) throws IOException {
 		Manifest manifest = new Manifest();
 		Attributes attributes = manifest.getMainAttributes();

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=1302250&r1=1302249&r2=1302250&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 Sun Mar 18 23:49:34 2012
@@ -26,13 +26,13 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.URL;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -107,6 +107,7 @@ public class AriesSubsystem implements S
 	private static final Logger LOGGER = LoggerFactory.getLogger(AriesSubsystem.class);
 	
 	private static final Map<String, AriesSubsystem> locationToSubsystem = Collections.synchronizedMap(new HashMap<String, AriesSubsystem>());
+	private static final ResourceReferences resourceReferences = new ResourceReferences();
 	private static final Map<Resource, Set<AriesSubsystem>> resourceToSubsystems = Collections.synchronizedMap(new HashMap<Resource, Set<AriesSubsystem>>());
 	
 	static synchronized Collection<AriesSubsystem> getSubsystems(Resource resource) {
@@ -316,8 +317,7 @@ public class AriesSubsystem implements S
 		BundleContext context = Activator.getInstance().getBundleContext();
 		for (long id : region.getBundleIds()) {
 			BundleRevision br = context.getBundle(id).adapt(BundleRevision.class);
-			addResourceToSubsystem(br, this);
-			constituents.add(br);
+			bundleInstalled(br);
 		}
 		// TODO End proof of concept.
 		LOGGER.debug(LOG_EXIT, "init");
@@ -416,11 +416,21 @@ public class AriesSubsystem implements S
 	
 	@Override
 	public List<Capability> getCapabilities(String namespace) {
-		if (namespace == null || namespace.equals(IdentityNamespace.IDENTITY_NAMESPACE)) {
+		if (IdentityNamespace.IDENTITY_NAMESPACE.equals(namespace)) {
 			Capability capability = new OsgiIdentityCapability(this, getSymbolicName(), getVersion(), getType());
-			return Arrays.asList(new Capability[]{capability});
+			return Collections.singletonList(capability);
 		}
-		return Collections.emptyList();
+		if (namespace == null) {
+			Capability capability = new OsgiIdentityCapability(this, getSymbolicName(), getVersion(), getType());
+			List<Capability> result = archive.getSubsystemManifest().toCapabilities(this);
+			result.add(capability);
+			return result;
+		}
+		List<Capability> result = archive.getSubsystemManifest().toCapabilities(this);
+		for (Iterator<Capability> i = result.iterator(); i.hasNext();)
+			if (!i.next().getNamespace().equals(namespace))
+				i.remove();
+		return result;
 	}
 
 	@Override
@@ -445,7 +455,13 @@ public class AriesSubsystem implements S
 
 	@Override
 	public List<Requirement> getRequirements(String namespace) {
-		return Collections.emptyList();
+		if (namespace == null)
+			return archive.getSubsystemManifest().toRequirements(this);
+		List<Requirement> result = archive.getSubsystemManifest().toRequirements(this);
+		for (Iterator<Requirement> i = result.iterator(); i.hasNext();)
+			if (!i.next().getNamespace().equals(namespace))
+				i.remove();
+		return result;
 	}
 
 	@Override
@@ -564,9 +580,8 @@ public class AriesSubsystem implements S
 				.getServiceProvider().getService(Coordinator.class)
 				.create(getSymbolicName() + '-' + getSubsystemId(), 0);
 		try {
-			// TODO Need to make sure the constituents are ordered by start level.
-			// TODO This doesn't start dependencies that are constituents in a parent subsystem.
-			for (Resource resource : constituents) {
+			// TODO Need to make sure the resources are ordered by start level.
+			for (Resource resource : resourceReferences.getResources(this)) {
 				startResource(resource, coordination);
 			}
 			setState(State.ACTIVE);
@@ -686,7 +701,7 @@ public class AriesSubsystem implements S
 		}
 		// For non-root subsystems, stop any remaining constituents.
 		if (!isRoot()){
-			for (Resource resource : constituents) {
+			for (Resource resource : resourceReferences.getResources(this)) {
 				// Don't stop the region context bundle.
 				if (ResourceHelper.getSymbolicNameAttribute(resource).startsWith(RegionContextBundleHelper.SYMBOLICNAME_PREFIX))
 					continue;
@@ -765,14 +780,6 @@ public class AriesSubsystem implements S
 		return region;
 	}
 	
-	private AriesSubsystem getConstituentOf(Resource resource, AriesSubsystem provisionTo, boolean transitive) {
-		// Transitive resources always become constituents of the subsystem to which they were provisioned.
-		if (transitive)
-			return provisionTo;
-		// Non-transitive resources become constituents of the subsystem in which they were declared.
-		return this;
-	}
-	
 	private DeploymentManifest getDeploymentManifest() throws IOException {
 		if (archive.getDeploymentManifest() == null) {
 			archive.setDeploymentManifest(new DeploymentManifest(
@@ -789,19 +796,6 @@ public class AriesSubsystem implements S
 		return archive.getDeploymentManifest();
 	}
 	
-	private AriesSubsystem getProvisionTo(Resource resource, boolean transitive) {
-		// Content resources are provisioned into the subsystem that declares
-		// them.
-		AriesSubsystem provisionTo = this;
-		if (transitive) {
-			// Transitive dependencies should be provisioned into the first
-			// subsystem that accepts dependencies.
-			while (provisionTo.archive.getSubsystemManifest().getSubsystemTypeHeader().getProvisionPolicyDirective().isRejectDependencies())
-				provisionTo = (AriesSubsystem)provisionTo.getParents().iterator().next();
-		}
-		return provisionTo;
-	}
-	
 	private synchronized void install(Coordination coordination) throws Exception {
 		if (!isFeature())
 			RegionContextBundleHelper.installRegionContextBundle(this);
@@ -893,7 +887,7 @@ public class AriesSubsystem implements S
 				return subsystem;
 			}
 			subsystem = new AriesSubsystem(location, ssr.getContent(), this);
-			installSubsystemResource(subsystem, coordination, false);
+			installResource(subsystem, coordination, false);
 			return subsystem;
 		}
 		catch (SubsystemException e) {
@@ -909,70 +903,99 @@ public class AriesSubsystem implements S
 		}
 	}
 
-	private void installBundleResource(Resource resource, Coordination coordination, boolean transitive) throws BundleException, IOException {
+	private Resource installBundleResource(Resource resource,
+			Coordination coordination, boolean transitive)
+			throws BundleException, IOException {
 		final BundleRevision revision;
-		AriesSubsystem provisionTo = getProvisionTo(resource, transitive);
 		if (resource instanceof BundleRevision) {
 			// This means the resource is an already installed bundle.
-			revision = (BundleRevision)resource;
-			// Need to simulate the install process since an install does not
-			// actually occur here, and the event hook is not called.
-			provisionTo.bundleInstalled(revision);
-		}
-		else {
-			InputStream content = ((RepositoryContent)resource).getContent();
-			String location = provisionTo.getSubsystemId() + "@" + provisionTo.getSymbolicName() + "@" + ResourceHelper.getSymbolicNameAttribute(resource);
-			ThreadLocalSubsystem.set(provisionTo);
-			Bundle bundle = provisionTo.region.installBundle(location, content);
-			revision = bundle.adapt(BundleRevision.class);
-			// Only need to add a participant when this subsystem is the actual
-			// installer of the bundle.
-			coordination.addParticipant(new Participant() {
-				public void ended(Coordination coordination) throws Exception {
-					// noop
-				}
-		
-				public void failed(Coordination coordination) throws Exception {
-					revision.getBundle().uninstall();
-				}
-			});
+			revision = (BundleRevision) resource;
+			// Transitive runtime resources need no further processing here.
+			if (!transitive) {
+				// Need to simulate the install process since an install does
+				// not
+				// actually occur here, and the event hook is not called.
+				bundleInstalled(revision);
+			}
+			return revision;
 		}
+		InputStream content = ((RepositoryContent) resource).getContent();
+		// By default, the resource is provisioned into this subsystem.
+		AriesSubsystem provisionTo = this;
+		if (transitive) {
+			// But transitive dependencies should be provisioned into the
+			// first subsystem that accepts dependencies.
+			while (provisionTo.archive.getSubsystemManifest()
+					.getSubsystemTypeHeader().getProvisionPolicyDirective()
+					.isRejectDependencies()) {
+				provisionTo = (AriesSubsystem) provisionTo.getParents()
+						.iterator().next();
+			}
+		}
+		String location = provisionTo.getSubsystemId() + "@"
+				+ provisionTo.getSymbolicName() + "@"
+				+ ResourceHelper.getSymbolicNameAttribute(resource);
+		ThreadLocalSubsystem.set(provisionTo);
+		Bundle bundle = provisionTo.region.installBundle(location, content);
+		revision = bundle.adapt(BundleRevision.class);
+		// Only need to add a participant when this subsystem is the actual
+		// installer of the bundle.
+		coordination.addParticipant(new Participant() {
+			public void ended(Coordination coordination) throws Exception {
+				// noop
+			}
+
+			public void failed(Coordination coordination) throws Exception {
+				revision.getBundle().uninstall();
+			}
+		});
+		return revision;
 	}
 
 	private void installResource(Resource resource, Coordination coordination, boolean transitive) throws Exception {
+		final Resource installed;
 		String type = ResourceHelper.getTypeAttribute(resource);
 		if (SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION.equals(type)
 				|| SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE.equals(type)
 				|| SubsystemConstants.SUBSYSTEM_TYPE_FEATURE.equals(type))
-			installSubsystemResource(resource, coordination, transitive);
-		else if (IdentityNamespace.TYPE_BUNDLE.equals(type))
-			installBundleResource(resource, coordination, transitive);
-		else if (IdentityNamespace.TYPE_FRAGMENT.equals(type))
-			installBundleResource(resource, coordination, transitive);
+			installed = installSubsystemResource(resource, coordination, transitive);
+		else if (IdentityNamespace.TYPE_BUNDLE.equals(type) ||
+				IdentityNamespace.TYPE_FRAGMENT.equals(type))
+			installed = installBundleResource(resource, coordination, transitive);
 		else
 			throw new SubsystemException("Unsupported resource type: " + type);
+		resourceReferences.addReference(this, installed);
+		coordination.addParticipant(new Participant() {
+			@Override
+			public void ended(Coordination coordination) throws Exception {
+				// noop
+			}
+
+			@Override
+			public void failed(Coordination coordination) throws Exception {
+				resourceReferences.removeReference(AriesSubsystem.this, installed);
+			}
+		});
 	}
 
-	private void installSubsystemResource(Resource resource, Coordination coordination, boolean transitive) throws Exception {
+	private Resource installSubsystemResource(Resource resource, Coordination coordination, boolean transitive) throws Exception {
 		final AriesSubsystem subsystem;
-		if (resource instanceof AriesSubsystem) {
-			subsystem = (AriesSubsystem)resource;
-			locationToSubsystem.put(subsystem.getLocation(), subsystem);
-		}
-		else if (resource instanceof SubsystemFileResource) {
+		if (resource instanceof SubsystemFileResource) {
 			SubsystemFileResource sfr = (SubsystemFileResource)resource;
 			subsystem = (AriesSubsystem)install(sfr.getLocation(), sfr.getContent(), coordination);
-			return;
-		}
-		else if (resource instanceof SubsystemDirectoryResource) {
-			SubsystemDirectoryResource sdr = (SubsystemDirectoryResource)resource;
-			subsystem = new AriesSubsystem(sdr.getArchive(), this);
-			locationToSubsystem.put(subsystem.getLocation(), subsystem);
+			return subsystem;
 		}
 		else if (resource instanceof RepositoryContent) {
 			String location = getSubsystemId() + "@" + getSymbolicName() + "@" + ResourceHelper.getSymbolicNameAttribute(resource);
 			subsystem = (AriesSubsystem)install(location, ((RepositoryContent)resource).getContent(), coordination);
-			return;
+			return subsystem;
+		}
+		else if (resource instanceof AriesSubsystem) {
+			subsystem = (AriesSubsystem)resource;
+		}
+		else if (resource instanceof SubsystemDirectoryResource) {
+			SubsystemDirectoryResource sdr = (SubsystemDirectoryResource)resource;
+			subsystem = new AriesSubsystem(sdr.getArchive(), this);
 		}
 		else {
 			throw new IllegalArgumentException("Unrecognized subsystem resource: " + resource);
@@ -982,7 +1005,7 @@ public class AriesSubsystem implements S
 		// before the child. This results in the child (i.e. this subsystem) being uninstalled as part
 		// of that process, but its state has not moved from INSTALLING to INSTALL_FAILED, which results
 		// in an eternal wait for a state change.
-		subsystemGraph.add(this, subsystem);
+		subsystemInstalled(subsystem);
 		coordination.addParticipant(new Participant() {
 			public void ended(Coordination coordination) throws Exception {
 				// noop
@@ -991,14 +1014,11 @@ public class AriesSubsystem implements S
 			public void failed(Coordination coordination) throws Exception {
 				subsystem.setState(State.INSTALL_FAILED);
 				subsystem.uninstall(false);
-				constituents.remove(subsystem);
-				removeResourceToSubsystem(subsystem, AriesSubsystem.this);
-				locationToSubsystem.remove(location);
+				subsystemUninstalled(subsystem);
 			}
 		});
-		addResourceToSubsystem(subsystem, this);
-		constituents.add(subsystem);
 		subsystem.install(coordination);
+		return subsystem;
 	}
 
 	private boolean isRoot() {
@@ -1261,6 +1281,20 @@ public class AriesSubsystem implements S
 		((AriesSubsystem)resource).stop();
 	}
 	
+	private synchronized void subsystemInstalled(AriesSubsystem subsystem) {
+		locationToSubsystem.put(subsystem.getLocation(), subsystem);
+		subsystemGraph.add(this, subsystem);
+		addResourceToSubsystem(subsystem, this);
+		constituents.add(subsystem);
+	}
+	
+	private synchronized void subsystemUninstalled(AriesSubsystem subsystem) {
+		constituents.remove(subsystem);
+		removeResourceToSubsystem(subsystem, this);
+		subsystemGraph.remove(subsystem);
+		locationToSubsystem.remove(subsystem.getLocation());
+	}
+	
 	private void uninstall(boolean changeState) {
 		if (changeState)
 			setState(State.UNINSTALLING);
@@ -1275,7 +1309,10 @@ public class AriesSubsystem implements S
 			}
 		}
 		// Uninstall any remaining constituents.
-		for (Resource resource : getConstituents()) {
+		for (Resource resource : resourceReferences.getResources(this)) {
+			// Don't uninstall a resource that is still referenced by other subsystems.
+			if (resourceReferences.getSubsystems(resource).size() > 1)
+				continue;
 			// Don't uninstall the region context bundle here.
 			if (ResourceHelper.getSymbolicNameAttribute(resource).startsWith(RegionContextBundleHelper.SYMBOLICNAME_PREFIX))
 				continue;
@@ -1323,6 +1360,7 @@ public class AriesSubsystem implements S
 					ResourceHelper.getTypeAttribute(resource)
 			});
 		}
+		resourceReferences.removeReference(this, resource);
 		String type = ResourceHelper.getTypeAttribute(resource);
 		if (SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION.equals(type)
 				|| SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE.equals(type)

Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceReferences.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceReferences.java?rev=1302250&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceReferences.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceReferences.java Sun Mar 18 23:49:34 2012
@@ -0,0 +1,77 @@
+package org.apache.aries.subsystem.core.internal;
+
+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 org.osgi.resource.Resource;
+import org.osgi.service.subsystem.Subsystem;
+
+public class ResourceReferences {
+	private final Map<Resource, Set<Subsystem>> resourceToSubsystems = new HashMap<Resource, Set<Subsystem>>();
+	private final Map<Subsystem, Set<Resource>> subsystemToResources = new HashMap<Subsystem, Set<Resource>>();
+	
+	public synchronized void addReference(Subsystem subsystem, Resource resource) {
+		addSubsystemToResource(subsystem, resource);
+		addResourceToSubsystem(subsystem, resource);
+	}
+	
+	public synchronized Collection<Resource> getResources(Subsystem subsystem) {
+		Collection<Resource> result = subsystemToResources.get(subsystem);
+		if (result == null)
+			result = Collections.emptyList();
+		return Collections.unmodifiableCollection(new ArrayList<Resource>(result));
+	}
+	
+	public synchronized Collection<Subsystem> getSubsystems(Resource resource) {
+		Collection<Subsystem> result = resourceToSubsystems.get(resource);
+		if (result == null)
+			result = Collections.emptyList();
+		return Collections.unmodifiableCollection(new ArrayList<Subsystem>(result));
+	}
+	
+	public synchronized void removeReference(Subsystem subsystem, Resource resource) {
+		removeResourceToSubsystem(subsystem, resource);
+		removeSubsystemToResource(subsystem, resource);
+	}
+	
+	private void addResourceToSubsystem(Subsystem subsystem, Resource resource) {
+		Set<Subsystem> subsystems = resourceToSubsystems.get(resource);
+		if (subsystems == null) {
+			subsystems = new HashSet<Subsystem>();
+			resourceToSubsystems.put(resource, subsystems);
+		}
+		subsystems.add(subsystem);
+	}
+	
+	private void addSubsystemToResource(Subsystem subsystem, Resource resource) {
+		Set<Resource> resources = subsystemToResources.get(subsystem);
+		if (resources == null) {
+			resources = new HashSet<Resource>();
+			subsystemToResources.put(subsystem, resources);
+		}
+		resources.add(resource);
+	}
+	
+	private void removeResourceToSubsystem(Subsystem subsystem, Resource resource) {
+		Set<Subsystem> subsystems = resourceToSubsystems.get(resource);
+		if (subsystems == null)
+			return;
+		subsystems.remove(subsystem);
+		if (subsystems.isEmpty())
+			resourceToSubsystems.remove(resource);
+	}
+	
+	private void removeSubsystemToResource(Subsystem subsystem, Resource resource) {
+		Set<Resource> resources = subsystemToResources.get(subsystem);
+		if (resources == null)
+			return;
+		resources.remove(resource);
+		if (resources.isEmpty())
+			subsystemToResources.remove(subsystem);
+	}
+}

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=1302250&r1=1302249&r2=1302250&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 Sun Mar 18 23:49:34 2012
@@ -71,7 +71,7 @@ public class BundleResource implements R
 			capabilities.addAll(eph.toCapabilities(this));
 		ImportPackageHeader iph = (ImportPackageHeader)manifest.getHeader(ImportPackageHeader.NAME);
 		if (iph != null)
-			requirements.addAll(iph.getRequirements(this));
+			requirements.addAll(iph.toRequirements(this));
 		RequireCapabilityHeader rch = (RequireCapabilityHeader)manifest.getHeader(RequireCapabilityHeader.NAME);
 		if (rch != null)
 			for (RequireCapabilityHeader.Clause clause : rch.getClauses())

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemStreamResource.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemStreamResource.java?rev=1302250&r1=1302249&r2=1302250&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemStreamResource.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemStreamResource.java Sun Mar 18 23:49:34 2012
@@ -9,10 +9,15 @@ import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map.Entry;
+import java.util.jar.Attributes;
 import java.util.jar.Manifest;
 
-import org.apache.aries.subsystem.core.archive.SubsystemSymbolicNameHeader;
+import org.apache.aries.subsystem.core.archive.Header;
+import org.apache.aries.subsystem.core.archive.HeaderFactory;
+import org.apache.aries.subsystem.core.archive.SubsystemManifest;
 import org.apache.aries.subsystem.core.archive.SubsystemTypeHeader;
+import org.apache.aries.subsystem.core.archive.SubsystemVersionHeader;
 import org.apache.aries.subsystem.core.internal.OsgiIdentityCapability;
 import org.apache.aries.subsystem.core.internal.SubsystemUri;
 import org.apache.aries.util.filesystem.FileSystem;
@@ -31,6 +36,7 @@ public class SubsystemStreamResource imp
 	private final byte[] content;
 	private final List<Capability> capabilities;
 	private final ICloseableDirectory directory;
+	private final List<Requirement> requirements;
 	
 	public SubsystemStreamResource(String location, InputStream content) throws IOException, URISyntaxException {
 		SubsystemUri uri = null;
@@ -58,30 +64,38 @@ public class SubsystemStreamResource imp
 			IOUtils.close(content);
 		}
 		Manifest manifest = ManifestProcessor.obtainManifestFromAppDir(directory, "OSGI-INF/SUBSYSTEM.MF");
-		String symbolicName = null;
-		Version version = Version.emptyVersion;
-		String type = SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION;
-		if (manifest != null) {
-			String value = manifest.getMainAttributes().getValue(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME);
-			if (value != null)
-				symbolicName = new SubsystemSymbolicNameHeader(value).getSymbolicName();
-			value = manifest.getMainAttributes().getValue(SubsystemConstants.SUBSYSTEM_VERSION);
-			if (value != null)
-				version = Version.parseVersion(value);
-			value = manifest.getMainAttributes().getValue(SubsystemConstants.SUBSYSTEM_TYPE);
-			if (value != null)
-				type = new SubsystemTypeHeader(value).getType();
-		}
+		Attributes attributes = manifest.getMainAttributes();
+		String symbolicName = attributes.getValue(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME);
 		if (symbolicName == null) {
 			if (uri == null)
 				throw new IllegalArgumentException("No symbolic name");
 			symbolicName = uri.getSymbolicName();
 		}
-		if (version == Version.emptyVersion && uri != null)
-			version = uri.getVersion();
-		List<Capability> capabilities = new ArrayList<Capability>(1);
-		capabilities.add(new OsgiIdentityCapability(this, symbolicName, version, type));
+		SubsystemManifest.Builder builder = new SubsystemManifest.Builder(symbolicName);
+		for (Entry<Object, Object> entry : attributes.entrySet()) {
+			String key = String.valueOf(entry.getKey());
+			if (key.equals(SubsystemManifest.SUBSYSTEM_SYMBOLICNAME))
+				continue;
+			builder.header(HeaderFactory.createHeader(key, String.valueOf(entry.getValue())));
+		}
+		SubsystemManifest subsystemManifest = builder.build();
+		SubsystemVersionHeader version = SubsystemVersionHeader.DEFAULT;
+		SubsystemTypeHeader type = SubsystemTypeHeader.DEFAULT;
+		Header<?> value = subsystemManifest.getSubsystemVersionHeader();
+		if (value != null)
+			version = (SubsystemVersionHeader)value;
+		value = subsystemManifest.getSubsystemTypeHeader();
+		if (value != null)
+			type = (SubsystemTypeHeader)value;
+		if (version.equals(SubsystemVersionHeader.DEFAULT) && uri != null)
+			version = new SubsystemVersionHeader(uri.getVersion());
+		List<Capability> capabilities;
+		List<Requirement> requirements;
+		capabilities = subsystemManifest.toCapabilities(this);
+		requirements = subsystemManifest.toRequirements(this);
+		capabilities.add(new OsgiIdentityCapability(this, symbolicName, version.getVersion(), type.getType()));
 		this.capabilities = Collections.unmodifiableList(capabilities);
+		this.requirements = Collections.unmodifiableList(requirements);
 	}
 	
 	public void close() {
@@ -90,9 +104,14 @@ public class SubsystemStreamResource imp
 	
 	@Override
 	public List<Capability> getCapabilities(String namespace) {
-		if (namespace == null || IdentityNamespace.IDENTITY_NAMESPACE.equals(namespace))
+		if (namespace == null)
 			return capabilities;
-		return Collections.emptyList();
+		ArrayList<Capability> result = new ArrayList<Capability>(capabilities.size());
+		for (Capability capability : capabilities)
+			if (namespace.equals(capability.getNamespace()))
+				result.add(capability);
+		result.trimToSize();
+		return result;
 	}
 
 	@Override
@@ -107,7 +126,14 @@ public class SubsystemStreamResource imp
 
 	@Override
 	public List<Requirement> getRequirements(String namespace) {
-		return Collections.emptyList();
+		if (namespace == null)
+			return requirements;
+		ArrayList<Requirement> result = new ArrayList<Requirement>(requirements.size());
+		for (Requirement requirement : requirements)
+			if (namespace.equals(requirement.getNamespace()))
+				result.add(requirement);
+		result.trimToSize();
+		return result;
 	}
 	
 	public String getSubsystemSymbolicName() {

Added: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/DependencyLifeCycleTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/DependencyLifeCycleTest.java?rev=1302250&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/DependencyLifeCycleTest.java (added)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/DependencyLifeCycleTest.java Sun Mar 18 23:49:34 2012
@@ -0,0 +1,132 @@
+package org.apache.aries.subsystem.itests;
+
+import java.io.IOException;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.service.subsystem.Subsystem;
+import org.osgi.service.subsystem.SubsystemConstants;
+
+@RunWith(JUnit4TestRunner.class)
+public class DependencyLifeCycleTest extends SubsystemTest {
+	/*
+	 * Subsystem-SymbolicName: application.a.esa
+	 * Subsystem-Content: bundle.a.jar
+	 */
+	private static final String APPLICATION_A = "application.a.esa";
+	/*
+	 * Bundle-SymbolicName: bundle.a.jar
+	 * Import-Package: x
+	 */
+	private static final String BUNDLE_A = "bundle.a.jar";
+	/*
+	 * Bundle-SymbolicName: bundle.b.jar
+	 * Export-Package: x
+	 */
+	private static final String BUNDLE_B = "bundle.b.jar";
+	
+	private static void createApplicationA() throws IOException {
+		createApplicationAManifest();
+		createSubsystem(APPLICATION_A, BUNDLE_A);
+	}
+	
+	private static void createApplicationAManifest() throws IOException {
+		Map<String, String> attributes = new HashMap<String, String>();
+		attributes.put(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME, APPLICATION_A);
+		attributes.put(SubsystemConstants.SUBSYSTEM_CONTENT, BUNDLE_A);
+		createManifest(APPLICATION_A + ".mf", attributes);
+	}
+	
+	private static void createBundleA() throws IOException {
+		Map<String, String> headers = new HashMap<String, String>();
+		headers.put(Constants.IMPORT_PACKAGE, "x");
+		createBundle(BUNDLE_A, headers);
+	}
+	
+	private static void createBundleB() throws IOException {
+		Map<String, String> headers = new HashMap<String, String>();
+		headers.put(Constants.EXPORT_PACKAGE, "x");
+		createBundle(BUNDLE_B, headers);
+	}
+	
+	private static boolean createdTestFiles;
+	@Before
+	public static void createTestFiles() throws Exception {
+		if (createdTestFiles)
+			return;
+		createBundleA();
+		createBundleB();
+		createApplicationA();
+		createdTestFiles = true;
+	}
+	
+	public void setUp() throws Exception {
+		super.setUp();
+		registerRepositoryService(BUNDLE_A, BUNDLE_B);
+	}
+	
+	@Test
+	public void testBundleDependencyInstall() throws Exception {
+		Subsystem subsystem = installSubsystemFromFile(APPLICATION_A);
+		try {
+			assertBundleState(Bundle.INSTALLED, BUNDLE_B, getRootSubsystem());
+		}
+		finally {
+			uninstallSubsystemSilently(subsystem);
+		}
+	}
+	
+	@Test
+	public void testBundleDependencyStart() throws Exception {
+		Subsystem subsystem = installSubsystemFromFile(APPLICATION_A);
+		try {
+			subsystem.start();
+			try {
+				assertBundleState(Bundle.ACTIVE, BUNDLE_B, getRootSubsystem());
+			}
+			finally {
+				stopSubsystemSilently(subsystem);
+			}
+		}
+		finally {
+			uninstallSubsystemSilently(subsystem);
+		}
+	}
+	
+	@Test
+	public void testBundleDependencyStop() throws Exception {
+		Subsystem subsystem = installSubsystemFromFile(APPLICATION_A);
+		try {
+			subsystem.start();
+			subsystem.stop();
+			assertBundleState(Bundle.RESOLVED, BUNDLE_B, getRootSubsystem());
+		}
+		finally {
+			uninstallSubsystemSilently(subsystem);
+		}
+	}
+	
+	@Test
+	public void testBundleDependencyUninstall() throws Exception {
+		Subsystem root = getRootSubsystem();
+		Subsystem subsystem = installSubsystemFromFile(APPLICATION_A);
+		try {
+			assertConstituent(root, BUNDLE_B);
+			Bundle bundle = getBundle(root, BUNDLE_B);
+			subsystem.uninstall();
+			assertBundleState(bundle, Bundle.UNINSTALLED);
+			assertNotConstituent(root, BUNDLE_B);
+		}
+		finally {
+			if (!EnumSet.of(Subsystem.State.UNINSTALLING, Subsystem.State.UNINSTALLED).contains(subsystem.getState()))
+				uninstallSubsystemSilently(subsystem);	
+		}
+	}
+}

Modified: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java?rev=1302250&r1=1302249&r2=1302250&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 Sun Mar 18 23:49:34 2012
@@ -229,17 +229,15 @@ public abstract class SubsystemTest exte
 	}
 	
 	protected void assertBundleState(int state, String symbolicName, Subsystem subsystem) {
-    	boolean found = false;
-    	for (Bundle bundle : subsystem.getBundleContext().getBundles()) {
-			if (symbolicName.equals(bundle.getSymbolicName())) { 
-				assertTrue("Wrong state: " + symbolicName + " [expected " + state + " but was " + bundle.getState() + "]", (bundle.getState() & state) != 0);
-				found = true;
-				break;
-			}
-		}
-    	assertTrue("Bundle '" + symbolicName + "' not found in region of '" + subsystem + "'", found);
+    	Bundle bundle = getBundle(subsystem, symbolicName);
+    	assertBundleState(bundle, state);
     }
 	
+	protected void assertBundleState(Bundle bundle, int state) {
+		assertNotNull("Bundle not found: " + bundle, bundle);
+		assertTrue("Wrong state: " + bundle + " [expected " + state + " but was " + bundle.getState() + "]", (bundle.getState() & state) != 0);
+	}
+	
 	protected void assertChild(Subsystem parent, Subsystem child) {
 		Collection<Subsystem> children = new ArrayList<Subsystem>(1);
 		children.add(child);
@@ -528,6 +526,15 @@ public abstract class SubsystemTest exte
 		write(name, fixture);
 	}
 	
+	protected Bundle getBundle(Subsystem subsystem, String symbolicName) {
+		for (Bundle bundle : subsystem.getBundleContext().getBundles()) {
+			if (symbolicName.equals(bundle.getSymbolicName())) { 
+				return bundle;
+			}
+		}
+		return null;
+	}
+	
 	protected Resource getConstituent(Subsystem subsystem, String symbolicName, Version version, String type) {
 		for (Resource resource : subsystem.getConstituents()) {
 			if (symbolicName.equals(ResourceHelper.getSymbolicNameAttribute(resource))) {