You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by jw...@apache.org on 2012/04/01 18:53:52 UTC

svn commit: r1308154 [1/2] - 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/subsys...

Author: jwross
Date: Sun Apr  1 16:53:51 2012
New Revision: 1308154

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

(1) Fixed a number of issues with calculating dependencies for various subsystem types in conjunction with share policy validation and provisioning.
(2) Updated region digraph version to gain access to new isAllowed method for testing sharing policies using a capability instead of a bundle.
(3) Temporarily disabled persistence tests as the code is undergoing a refactoring that will change the persisted directory structure.

Added:
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SharingPolicyValidator.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/ApplicationResource.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/BundleResource.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/CompositeResource.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/DeploymentManifest.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/FeatureResource.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/SubsystemArchive.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/SubsystemManifest.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/SubsystemResource.java
Modified:
    aries/trunk/subsystem/pom.xml
    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/ImportPackageRequirement.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/RequireCapabilityHeader.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireCapabilityRequirement.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemArchive.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/SubsystemImportServiceRequirement.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/internal/SubsystemEnvironment.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemServiceRegistrar.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemUri.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/SubsystemFileResource.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/FeatureTest.java

Modified: aries/trunk/subsystem/pom.xml
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/pom.xml?rev=1308154&r1=1308153&r2=1308154&view=diff
==============================================================================
--- aries/trunk/subsystem/pom.xml (original)
+++ aries/trunk/subsystem/pom.xml Sun Apr  1 16:53:51 2012
@@ -186,7 +186,7 @@
                                     <artifactId>org.eclipse.equinox.region</artifactId>
                                     <version>3.8.0-SNAPSHOT</version>
                                     <packaging>jar</packaging>
-                                    <downloadUrl>http://www.eclipse.org/downloads/download.php?file=/equinox/drops/N20120223-2000/org.eclipse.equinox.region_1.1.0.N20120223-2000.jar&amp;url=http://download.eclipse.org/equinox/drops/N20120223-2000/org.eclipse.equinox.region_1.1.0.N20120223-2000.jar&amp;mirror_id=1</downloadUrl>
+                                    <downloadUrl>http://www.eclipse.org/downloads/download.php?file=/equinox/drops/S-3.8M6-201203141800/org.eclipse.equinox.region_1.1.0.v20120227-1635.jar&amp;url=http://download.eclipse.org/equinox/drops/S-3.8M6-201203141800/org.eclipse.equinox.region_1.1.0.v20120227-1635.jar&amp;mirror_id=1</downloadUrl>
                                 </artifactItem>
                                 <artifactItem>
                                     <groupId>org.eclipse.osgi</groupId>

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=1308154&r1=1308153&r2=1308154&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 Apr  1 16:53:51 2012
@@ -32,6 +32,26 @@ import org.osgi.service.subsystem.Subsys
 import org.osgi.service.subsystem.SubsystemException;
 
 public class DeploymentManifest {
+	public static class Builder {
+		private Map<String, Header<?>> headers = new HashMap<String, Header<?>>();
+		
+		public DeploymentManifest build() {
+			return new DeploymentManifest(headers);
+		}
+		
+		public Builder header(Header<?> value) {
+			if (value != null)
+				headers.put(value.getName(), value);
+			return this;
+		}
+		
+		public Builder manifest(SubsystemManifest value) {
+			for (Entry<String, Header<?>> entry : value.getHeaders().entrySet())
+				header(entry.getValue());
+			return this;
+		}
+	}
+	
 	public static final String DEPLOYED_CONTENT = SubsystemConstants.DEPLOYED_CONTENT;
 	public static final String DEPLOYMENT_MANIFESTVERSION = SubsystemConstants.DEPLOYMENT_MANIFESTVERSION;
 	public static final String EXPORT_PACKAGE = Constants.EXPORT_PACKAGE;
@@ -52,6 +72,16 @@ public class DeploymentManifest {
 	
 	private final Map<String, Header<?>> headers;
 	
+	public DeploymentManifest(java.util.jar.Manifest manifest) {
+		headers = new HashMap<String, Header<?>>();
+		for (Entry<Object, Object> entry : manifest.getMainAttributes().entrySet()) {
+			String key = String.valueOf(entry.getKey());
+			if (key.equals(SubsystemManifest.SUBSYSTEM_SYMBOLICNAME))
+				continue;
+			headers.put(key, HeaderFactory.createHeader(key, String.valueOf(entry.getValue())));
+		}
+	}
+	
 	public DeploymentManifest(File file) throws FileNotFoundException, IOException {
 		Manifest manifest = ManifestProcessor.parseManifest(new FileInputStream(file));
 		Attributes attributes = manifest.getMainAttributes();
@@ -162,6 +192,11 @@ public class DeploymentManifest {
 		this.headers = Collections.unmodifiableMap(headers);
 	}
 	
+	private DeploymentManifest(Map<String, Header<?>> headers) {
+		Map<String, Header<?>> map = new HashMap<String, Header<?>>(headers);
+		this.headers = Collections.unmodifiableMap(map);
+	}
+	
 	public DeployedContentHeader getDeployedContentHeader() {
 		return (DeployedContentHeader)getHeaders().get(DEPLOYED_CONTENT);
 	}

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ImportPackageRequirement.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ImportPackageRequirement.java?rev=1308154&r1=1308153&r2=1308154&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ImportPackageRequirement.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ImportPackageRequirement.java Sun Apr  1 16:53:51 2012
@@ -16,10 +16,6 @@ public class ImportPackageRequirement ex
 	private final Map<String, String> directives = new HashMap<String, String>(1);
 	private final Resource resource;
 	
-	public ImportPackageRequirement(ImportPackageHeader.Clause clause) {
-		this(clause, null);
-	}
-	
 	public ImportPackageRequirement(ImportPackageHeader.Clause clause, Resource resource) {
 		Collection<String> packageNames = clause.getPackageNames();
 		if (packageNames.isEmpty() || packageNames.size() > 1)

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=1308154&r1=1308153&r2=1308154&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 Apr  1 16:53:51 2012
@@ -135,8 +135,8 @@ public class RequireBundleHeader impleme
 			return path;
 		}
 		
-		public RequireBundleRequirement toRequirement() {
-			return new RequireBundleRequirement(this);
+		public RequireBundleRequirement toRequirement(Resource resource) {
+			return new RequireBundleRequirement(this, resource);
 		}
 		
 		@Override
@@ -193,7 +193,7 @@ public class RequireBundleHeader impleme
 	public List<RequireBundleRequirement> toRequirements(Resource resource) {
 		List<RequireBundleRequirement> requirements = new ArrayList<RequireBundleRequirement>(clauses.size());
 		for (Clause clause : clauses)
-			requirements.add(clause.toRequirement());
+			requirements.add(clause.toRequirement(resource));
 		return requirements;
 	}
 	

Modified: 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=1308154&r1=1308153&r2=1308154&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireBundleRequirement.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireBundleRequirement.java Sun Apr  1 16:53:51 2012
@@ -15,10 +15,6 @@ public class RequireBundleRequirement ex
 	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("(&(")

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=1308154&r1=1308153&r2=1308154&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 Apr  1 16:53:51 2012
@@ -117,8 +117,8 @@ public class RequireCapabilityHeader imp
 			return getNamespace();
 		}
 		
-		public RequireCapabilityRequirement toRequirement() {
-			return new RequireCapabilityRequirement(this);
+		public RequireCapabilityRequirement toRequirement(Resource resource) {
+			return new RequireCapabilityRequirement(this, resource);
 		}
 		
 		@Override
@@ -175,7 +175,7 @@ public class RequireCapabilityHeader imp
 	public List<RequireCapabilityRequirement> toRequirements(Resource resource) {
 		List<RequireCapabilityRequirement> requirements = new ArrayList<RequireCapabilityRequirement>(clauses.size());
 		for (Clause clause : clauses)
-			requirements.add(clause.toRequirement());
+			requirements.add(clause.toRequirement(resource));
 		return requirements;
 	}
 	

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireCapabilityRequirement.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireCapabilityRequirement.java?rev=1308154&r1=1308153&r2=1308154&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireCapabilityRequirement.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/RequireCapabilityRequirement.java Sun Apr  1 16:53:51 2012
@@ -15,10 +15,6 @@ public class RequireCapabilityRequiremen
 	private final String namespace;
 	private final Resource resource;
 	
-	public RequireCapabilityRequirement(RequireCapabilityHeader.Clause clause) {
-		this(clause, null);
-	}
-	
 	public RequireCapabilityRequirement(RequireCapabilityHeader.Clause clause, Resource resource) {
 		namespace = clause.getNamespace();
 		Directive filter = clause.getDirective(RequireCapabilityHeader.Clause.DIRECTIVE_FILTER);

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemArchive.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemArchive.java?rev=1308154&r1=1308153&r2=1308154&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemArchive.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemArchive.java Sun Apr  1 16:53:51 2012
@@ -11,12 +11,14 @@ import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
 
 import org.apache.aries.subsystem.core.ResourceHelper;
 import org.apache.aries.subsystem.core.resource.BundleResource;
 import org.apache.aries.subsystem.core.resource.SubsystemDirectoryResource;
 import org.apache.aries.subsystem.core.resource.SubsystemFileResource;
+import org.apache.aries.subsystem.core.resource.tmp.SubsystemResource;
 import org.osgi.resource.Capability;
 import org.osgi.resource.Requirement;
 import org.osgi.resource.Resource;
@@ -28,16 +30,24 @@ public class SubsystemArchive implements
 	private static final Logger logger = LoggerFactory.getLogger(SubsystemArchive.class);
 	
 	private final File directory;
-	private final Map<Resource, URL> resources = new HashMap<Resource, URL>();
+	private final Collection<Resource> resources;
 	
 	private DeploymentManifest deploymentManifest;
 	private SubsystemManifest subsystemManifest;
 	
+	public SubsystemArchive(SubsystemResource resource, File directory) {
+		this.directory = directory;
+		resources = resource.getResources();
+		deploymentManifest = resource.getDeploymentManifest();
+		subsystemManifest = resource.getSubsystemManifest();
+	}
+	
 	public SubsystemArchive(File content) throws Exception {
 		logger.debug(LOG_ENTRY, "init", content);
 		if (!content.isDirectory())
 			throw new IllegalArgumentException("Not a directory: " + content.getAbsolutePath());
 		directory = content;
+		resources = new HashSet<Resource>();
 		for (File file : content.listFiles()) {
 			if (file.isDirectory() && "OSGI-INF".equals(file.getName())) {
 				for (File f : file.listFiles()) {
@@ -58,7 +68,7 @@ public class SubsystemArchive implements
 	public synchronized Collection<Capability> findProviders(Requirement requirement) {
 		logger.debug(LOG_ENTRY, "findProviders", requirement);
 		Collection<Capability> capabilities = new ArrayList<Capability>(1);
-		for (Resource resource : resources.keySet()) {
+		for (Resource resource : resources) {
 			logger.debug("Evaluating resource: " + resource);
 			for (Capability capability : resource.getCapabilities(requirement.getNamespace())) {
 				logger.debug("Evaluating capability: " + capability);
@@ -85,7 +95,7 @@ public class SubsystemArchive implements
 	}
 	
 	public Collection<Resource> getResources() {
-		return resources.keySet();
+		return resources;
 	}
 	
 	public synchronized SubsystemManifest getSubsystemManifest() {
@@ -130,13 +140,13 @@ public class SubsystemArchive implements
 	private void processResource(File file) throws Exception {
 		String name = file.getName();
 		if (file.isDirectory() && name.startsWith("subsystem"))
-			resources.put(new SubsystemDirectoryResource(file), file.toURI().toURL());
+			resources.add(new SubsystemDirectoryResource(file));
 		else if (name.endsWith(".jar")) {
 			URL url = file.toURI().toURL();
-			resources.put(BundleResource.newInstance(url), url);
+			resources.add(BundleResource.newInstance(url));
 		}
 		// TODO Add to constants.
 		else if (name.endsWith(".esa") && !name.startsWith("subsystem"))
-			resources.put(new SubsystemFileResource(file), file.toURI().toURL());
+			resources.add(new SubsystemFileResource(file));
 	}
 }

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=1308154&r1=1308153&r2=1308154&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 Apr  1 16:53:51 2012
@@ -110,8 +110,8 @@ public class SubsystemImportServiceHeade
 			return path;
 		}
 		
-		public SubsystemImportServiceRequirement toRequirement() {
-			return new SubsystemImportServiceRequirement(this);
+		public SubsystemImportServiceRequirement toRequirement(Resource resource) {
+			return new SubsystemImportServiceRequirement(this, resource);
 		}
 		
 		@Override
@@ -159,7 +159,7 @@ public class SubsystemImportServiceHeade
 	public List<SubsystemImportServiceRequirement> toRequirements(Resource resource) {
 		List<SubsystemImportServiceRequirement> requirements = new ArrayList<SubsystemImportServiceRequirement>(clauses.size());
 		for (Clause clause : clauses)
-			requirements.add(clause.toRequirement());
+			requirements.add(clause.toRequirement(resource));
 		return requirements;
 	}
 	

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemImportServiceRequirement.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemImportServiceRequirement.java?rev=1308154&r1=1308153&r2=1308154&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemImportServiceRequirement.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemImportServiceRequirement.java Sun Apr  1 16:53:51 2012
@@ -17,10 +17,6 @@ public class SubsystemImportServiceRequi
 	private final Map<String, String> directives = new HashMap<String, String>(1);
 	private final Resource resource;
 	
-	public SubsystemImportServiceRequirement(SubsystemImportServiceHeader.Clause clause) {
-		this(clause, null);
-	}
-	
 	public SubsystemImportServiceRequirement(
 			SubsystemImportServiceHeader.Clause clause, Resource resource) {
 		StringBuilder builder = new StringBuilder("(&(")

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=1308154&r1=1308153&r2=1308154&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 Apr  1 16:53:51 2012
@@ -15,6 +15,7 @@ import java.util.Map.Entry;
 import java.util.jar.Attributes;
 import java.util.jar.Manifest;
 
+import org.apache.aries.subsystem.core.internal.OsgiIdentityCapability;
 import org.apache.aries.util.manifest.ManifestProcessor;
 import org.osgi.framework.Constants;
 import org.osgi.framework.Version;
@@ -27,10 +28,6 @@ public class SubsystemManifest {
 	public static class Builder {
 		private Map<String, Header<?>> headers = new HashMap<String, Header<?>>();
 		
-		public Builder(String symbolicName) {
-			headers.put(SUBSYSTEM_SYMBOLICNAME, new SubsystemSymbolicNameHeader(symbolicName));
-		}
-		
 		public SubsystemManifest build() {
 			return new SubsystemManifest(headers);
 		}
@@ -53,6 +50,20 @@ public class SubsystemManifest {
 			return this;
 		}
 		
+		public Builder manifest(SubsystemManifest value) {
+			for (Entry<String, Header<?>> entry : value.getHeaders().entrySet())
+				header(entry.getValue());
+			return this;
+		}
+		
+		public Builder symbolicName(String value) {
+			return value == null ? this : symbolicName(new SubsystemSymbolicNameHeader(value));
+		}
+		
+		public Builder symbolicName(SubsystemSymbolicNameHeader value) {
+			return header(value);
+		}
+		
 		public Builder type(String value) {
 			return value == null ? this : type(new SubsystemTypeHeader(value));
 		}
@@ -90,6 +101,15 @@ public class SubsystemManifest {
 	public static final String SUBSYSTEM_TYPE = SubsystemConstants.SUBSYSTEM_TYPE;
 	public static final String SUBSYSTEM_VERSION = SubsystemConstants.SUBSYSTEM_VERSION;
 	
+	private static Map<String, Header<?>> parseHeaders(java.util.jar.Manifest manifest) {
+		Map<String, Header<?>> result = new HashMap<String, Header<?>>();
+		for (Entry<Object, Object> entry : manifest.getMainAttributes().entrySet()) {
+			String key = String.valueOf(entry.getKey());
+			result.put(key, HeaderFactory.createHeader(key, String.valueOf(entry.getValue())));
+		}
+		return result;
+	}
+	
 	private static void fillInDefaults(Map<String, Header<?>> headers) {
 		Header<?> header = headers.get(SUBSYSTEM_VERSION);
 		if (header == null) {
@@ -108,6 +128,10 @@ public class SubsystemManifest {
 		this.headers = Collections.unmodifiableMap(map);
 	}
 	
+	public SubsystemManifest(java.util.jar.Manifest manifest) {
+		this(parseHeaders(manifest));
+	}
+	
 	public SubsystemManifest(File file) throws FileNotFoundException, IOException {
 		Manifest manifest = ManifestProcessor.parseManifest(new FileInputStream(file));
 		Attributes attributes = manifest.getMainAttributes();
@@ -196,12 +220,17 @@ public class SubsystemManifest {
 	}
 	
 	public List<Capability> toCapabilities(Resource resource) {
-		ArrayList<Capability> requirements = new ArrayList<Capability>();
+		ArrayList<Capability> capabilities = new ArrayList<Capability>();
 		for (Header<?> header : headers.values())
 			if (header instanceof CapabilityHeader)
-				requirements.addAll(((CapabilityHeader<?>)header).toCapabilities(resource));
-		requirements.trimToSize();
-		return requirements;
+				capabilities.addAll(((CapabilityHeader<?>)header).toCapabilities(resource));
+		capabilities.add(new OsgiIdentityCapability(
+				resource,
+				getSubsystemSymbolicNameHeader().getSymbolicName(),
+				getSubsystemVersionHeader().getVersion(),
+				getSubsystemTypeHeader().getType()));
+		capabilities.trimToSize();
+		return capabilities;
 	}
 	
 	public List<Requirement> toRequirements(Resource resource) {

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=1308154&r1=1308153&r2=1308154&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 Apr  1 16:53:51 2012
@@ -24,6 +24,7 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -68,7 +69,7 @@ import org.apache.aries.subsystem.core.a
 import org.apache.aries.subsystem.core.archive.SubsystemTypeHeader;
 import org.apache.aries.subsystem.core.resource.SubsystemDirectoryResource;
 import org.apache.aries.subsystem.core.resource.SubsystemFileResource;
-import org.apache.aries.subsystem.core.resource.SubsystemStreamResource;
+import org.apache.aries.subsystem.core.resource.tmp.SubsystemResource;
 import org.apache.aries.util.io.IOUtils;
 import org.eclipse.equinox.region.Region;
 import org.eclipse.equinox.region.RegionDigraph;
@@ -240,7 +241,7 @@ public class AriesSubsystem implements S
 	private final SubsystemArchive archive;
 	private final Set<Resource> constituents = Collections.synchronizedSet(new HashSet<Resource>());
 	private final File directory;
-	private final SubsystemEnvironment environment;
+//	private final SubsystemEnvironment environment;
 	private final long id;
 	private final String location;
 	private final Region region;
@@ -277,8 +278,8 @@ public class AriesSubsystem implements S
 			// This is the first time the root subsystem has been initialized in
 			// this framework or a framework clean start was requested.
 			SubsystemUri uri = new SubsystemUri(ROOT_LOCATION);
-			subsystemManifest = new SubsystemManifest.Builder(
-					uri.getSymbolicName())
+			subsystemManifest = new SubsystemManifest.Builder()
+					.symbolicName(uri.getSymbolicName())
 					.version(uri.getVersion())
 					.content(archive.getResources())
 					.type(SubsystemTypeHeader.TYPE_APPLICATION
@@ -292,17 +293,19 @@ public class AriesSubsystem implements S
 		else {
 			// Need to generate a new subsystem manifest in order to generated a new deployment manifest based
 			// on any persisted resources.
-			subsystemManifest = new SubsystemManifest.Builder(getSymbolicName())
+			subsystemManifest = new SubsystemManifest.Builder()
+					.symbolicName(getSymbolicName())
 					.version(getVersion()).content(archive.getResources())
 					.build();
 		}
-		environment = new SubsystemEnvironment(this);
+//		environment = new SubsystemEnvironment(this);
 		// The root subsystem establishes the subsystem graph;
 		subsystemGraph = new SubsystemGraph(this);
 		archive.setDeploymentManifest(new DeploymentManifest(
 				deploymentManifest, 
 				subsystemManifest, 
-				environment,
+//				environment,
+				new SubsystemEnvironment(this),
 				autostart,
 				id,
 				lastId,
@@ -348,7 +351,7 @@ public class AriesSubsystem implements S
 			copyContent(content, zipFile);
 			unzipContent(zipFile, directory);
 			archive = new SubsystemArchive(directory);
-			environment = new SubsystemEnvironment(this);
+//			environment = new SubsystemEnvironment(this);
 			// Make sure the relevant headers are derived, if absent.
 			archive.setSubsystemManifest(new SubsystemManifest(
 					archive.getSubsystemManifest(),
@@ -372,7 +375,41 @@ public class AriesSubsystem implements S
 		subsystemGraph = parent.subsystemGraph;
 	}
 	
+	public AriesSubsystem(SubsystemResource resource, AriesSubsystem parent) throws Exception {
+		subsystemGraph = parent.subsystemGraph;
+		this.location = resource.getLocation();
+		id = SubsystemIdentifier.getNextId();
+		String directoryName = "subsystem" + id;
+//		String fileName = directoryName + ".esa";
+//		File zipFile = new File(parent.directory, fileName);
+		directory = new File(Activator.getInstance().getBundleContext().getDataFile(""), directoryName);
+		if (!directory.mkdir())
+			throw new IOException("Unable to make directory for " + directory.getCanonicalPath());
+		try {
+//			copyContent(resource.getContent(), zipFile);
+//			unzipContent(zipFile, directory);
+			archive = new SubsystemArchive(resource, directory);
+			archive.setSubsystemManifest(resource.getSubsystemManifest());
+			if (resource.getDeploymentManifest() != null)
+				archive.setDeploymentManifest(resource.getDeploymentManifest());
+			SubsystemManifestValidator.validate(this, archive.getSubsystemManifest());
+			// Unscoped subsystems don't get their own region. They share the region with their scoped parent.
+			if (isFeature())
+				region = parent.region;
+			else
+				region = createRegion(getSymbolicName() + ';' + getVersion() + ';' + getType() + ';' + getSubsystemId());
+		}
+		catch (Throwable t) {
+//			deleteFile(directory);
+//			deleteFile(zipFile);
+			if (t instanceof SubsystemException)
+				throw (SubsystemException)t;
+			throw new SubsystemException(t);
+		}
+	}
+	
 	public AriesSubsystem(SubsystemArchive archive, AriesSubsystem parent) throws Exception {
+		subsystemGraph = parent.subsystemGraph;
 		this.archive = archive;
 		DeploymentManifest manifest = archive.getDeploymentManifest();
 		if (manifest == null)
@@ -382,13 +419,12 @@ public class AriesSubsystem implements S
 		location = manifest.getHeaders().get(DeploymentManifest.ARIESSUBSYSTEM_LOCATION).getValue();
 		String directoryName = "subsystem" + id;
 		directory = new File(parent.directory, directoryName);
-		environment = new SubsystemEnvironment(this);
+//		environment = new SubsystemEnvironment(this);
 		// Unscoped subsystems don't get their own region. They share the region with their scoped parent.
 		if (isFeature())
 			region = parent.region;
 		else
 			region = createRegion(getSymbolicName() + ';' + getVersion() + ';' + getType() + ';' + getSubsystemId());
-		subsystemGraph = parent.subsystemGraph;
 	}
 	
 	public SubsystemArchive getArchive() {
@@ -781,19 +817,20 @@ public class AriesSubsystem implements S
 		return region;
 	}
 	
-	private DeploymentManifest getDeploymentManifest() throws IOException {
-		if (archive.getDeploymentManifest() == null) {
+	private DeploymentManifest getDeploymentManifest() throws IOException, URISyntaxException {
+//		if (archive.getDeploymentManifest() == null) {
 			archive.setDeploymentManifest(new DeploymentManifest(
-					null,
+					archive.getDeploymentManifest(),
 					archive.getSubsystemManifest(), 
-					environment,
+//					environment,
+					new SubsystemEnvironment(this),
 					autostart,
 					id,
 					SubsystemIdentifier.getLastId(),
 					location,
 					true,
 					false));
-		}
+//		}
 		return archive.getDeploymentManifest();
 	}
 	
@@ -825,8 +862,14 @@ public class AriesSubsystem implements S
 					}
 				});
 		List<Resource> transitiveDependencies = new ArrayList<Resource>();
+		// Set up the sharing policy before installing the resources so that the
+		// environment can filter out capabilities from dependencies being
+		// provisioned to regions that are out of scope. This doesn't hurt
+		// anything since the resources are disabled from resolving anyway.
+		setImportIsolationPolicy();
 		DeploymentManifest manifest = getDeploymentManifest();
 		DeployedContentHeader contentHeader = manifest.getDeployedContentHeader();
+		SubsystemEnvironment environment = new SubsystemEnvironment(this);
 		if (contentHeader != null) {
 			for (DeployedContent content : contentHeader.getDeployedContents()) {
 				Collection<Capability> capabilities = environment.findProviders(
@@ -848,46 +891,45 @@ public class AriesSubsystem implements S
 				transitiveDependencies.add(resource);
 			}
 		}
-		// Install the content resources.
-		for (Resource resource : contentResources) {
-			installResource(resource, coordination, false);
-		}
 		// Discover and install transitive dependencies.
 		for (Resource resource : transitiveDependencies) {
 			installResource(resource, coordination, true);
 		}
+		// Install the content resources.
+		for (Resource resource : contentResources) {
+			installResource(resource, coordination, false);
+		}
 		setState(State.INSTALLED);
-		setImportIsolationPolicy();
 		if (autostart)
 			start();
 	}
 	
 	private synchronized Subsystem install(String location, InputStream content, Coordination coordination) throws SubsystemException {
-		SubsystemStreamResource ssr = null;
+		SubsystemResource ssr = null;
 		try {
 			TargetRegion region = new TargetRegion(this);
-			ssr = new SubsystemStreamResource(location, content);
+			ssr = SubsystemResource.newInstance(location, content);
 			AriesSubsystem subsystem = locationToSubsystem.get(location);
 			if (subsystem != null) {
 				if (!region.contains(subsystem))
 					throw new SubsystemException("Location already exists but existing subsystem is not part of target region: " + location);
-				if (!(subsystem.getSymbolicName().equals(ssr.getSubsystemSymbolicName())
-						&& subsystem.getVersion().equals(ssr.getSubsystemVersion())
-						&& subsystem.getType().equals(ssr.getSubsystemType())))
+				if (!(subsystem.getSymbolicName().equals(ssr.getSubsystemManifest().getSubsystemSymbolicNameHeader().getSymbolicName())
+						&& subsystem.getVersion().equals(ssr.getSubsystemManifest().getSubsystemVersionHeader().getVersion())
+						&& subsystem.getType().equals(ssr.getSubsystemManifest().getSubsystemTypeHeader().getType())))
 					throw new SubsystemException("Location already exists but symbolic name, version, and type are not the same: " + location);
-				subsystemGraph.add(this, subsystem);
-				constituents.add(subsystem);
+				subsystemInstalled(subsystem);
 				return subsystem;
 			}
-			subsystem = (AriesSubsystem)region.find(ssr.getSubsystemSymbolicName(), ssr.getSubsystemVersion());
+			subsystem = (AriesSubsystem)region.find(
+					ssr.getSubsystemManifest().getSubsystemSymbolicNameHeader().getSymbolicName(), 
+					ssr.getSubsystemManifest().getSubsystemVersionHeader().getVersion());
 			if (subsystem != null) {
-				if (!subsystem.getType().equals(ssr.getSubsystemType()))
+				if (!subsystem.getType().equals(ssr.getSubsystemManifest().getSubsystemTypeHeader().getType()))
 					throw new SubsystemException("Subsystem already exists in target region but has a different type: " + location);
-				subsystemGraph.add(this, subsystem);
-				constituents.add(subsystem);
+				subsystemInstalled(subsystem);
 				return subsystem;
 			}
-			subsystem = new AriesSubsystem(location, ssr.getContent(), this);
+			subsystem = new AriesSubsystem(ssr, this);
 			installResource(subsystem, coordination, false);
 			return subsystem;
 		}
@@ -898,8 +940,8 @@ public class AriesSubsystem implements S
 			throw new SubsystemException(e);
 		}
 		finally {
-			if (ssr != null)
-				ssr.close();
+//			if (ssr != null)
+//				ssr.close();
 			IOUtils.close(content);
 		}
 	}
@@ -914,8 +956,7 @@ public class AriesSubsystem implements S
 			// 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.
+				// not actually occur here, and the event hook is not called.
 				bundleInstalled(revision);
 			}
 			return revision;
@@ -998,6 +1039,9 @@ public class AriesSubsystem implements S
 			SubsystemDirectoryResource sdr = (SubsystemDirectoryResource)resource;
 			subsystem = new AriesSubsystem(sdr.getArchive(), this);
 		}
+		else if (resource instanceof SubsystemResource) {
+			subsystem = new AriesSubsystem((SubsystemResource)resource, this);
+		}
 		else {
 			throw new IllegalArgumentException("Unrecognized subsystem resource: " + resource);
 		}
@@ -1054,7 +1098,7 @@ public class AriesSubsystem implements S
 		}
 	}
 	
-	private void setExportIsolationPolicy() throws InvalidSyntaxException, IOException, BundleException {
+	private void setExportIsolationPolicy() throws InvalidSyntaxException, IOException, BundleException, URISyntaxException {
 		if (isRoot())
 			// Nothing to do if this is the root subsystem.
 			return;
@@ -1121,7 +1165,7 @@ public class AriesSubsystem implements S
 		}
 	}
 
-	private void setImportIsolationPolicy() throws BundleException, IOException, InvalidSyntaxException {
+	private void setImportIsolationPolicy() throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
 		if (isRoot())
 			// Nothing to do if this is the root subsystem.
 			return;
@@ -1134,17 +1178,17 @@ public class AriesSubsystem implements S
 		if (isApplication() || isComposite()) {
 			// Both applications and composites have Import-Package headers that require processing.
 			// In the case of applications, the header is generated.
-			Header<?> header = getDeploymentManifest().getImportPackageHeader();
+			Header<?> header = archive.getSubsystemManifest().getImportPackageHeader();
 			setImportIsolationPolicy(builder, (ImportPackageHeader)header);
 			// Both applications and composites have Require-Capability headers that require processing.
 			// In the case of applications, the header is generated.
-			header = getDeploymentManifest().getRequireCapabilityHeader();
+			header = archive.getSubsystemManifest().getRequireCapabilityHeader();
 			setImportIsolationPolicy(builder, (RequireCapabilityHeader)header);
 			// Both applications and composites have Subsystem-ImportService headers that require processing.
 			// In the case of applications, the header is generated.
-			header = getDeploymentManifest().getSubsystemImportServiceHeader();
+			header = archive.getSubsystemManifest().getSubsystemImportServiceHeader();
 			setImportIsolationPolicy(builder, (SubsystemImportServiceHeader)header);
-			header = getDeploymentManifest().getRequireBundleHeader();
+			header = archive.getSubsystemManifest().getRequireBundleHeader();
 			setImportIsolationPolicy(builder, (RequireBundleHeader)header);
 		}
 		if (isApplication()) {
@@ -1162,12 +1206,12 @@ public class AriesSubsystem implements S
 		from.connectRegion(to, regionFilter);
 	}
 	
-	private static void setImportIsolationPolicy(RegionFilterBuilder builder, ImportPackageHeader header) throws InvalidSyntaxException {
+	private void setImportIsolationPolicy(RegionFilterBuilder builder, ImportPackageHeader header) throws InvalidSyntaxException {
 		if (header == null)
 			return;
 		String policy = RegionFilter.VISIBLE_PACKAGE_NAMESPACE;
 		for (ImportPackageHeader.Clause clause : header.getClauses()) {
-			ImportPackageRequirement requirement = new ImportPackageRequirement(clause);
+			ImportPackageRequirement requirement = new ImportPackageRequirement(clause, this);
 			String filter = requirement.getDirectives().get(ImportPackageRequirement.DIRECTIVE_FILTER);
 			if (LOGGER.isDebugEnabled())
 				LOGGER.debug("Allowing " + policy + " of " + filter);
@@ -1175,11 +1219,11 @@ public class AriesSubsystem implements S
 		}
 	}
 	
-	private static void setImportIsolationPolicy(RegionFilterBuilder builder, RequireBundleHeader header) throws InvalidSyntaxException {
+	private void setImportIsolationPolicy(RegionFilterBuilder builder, RequireBundleHeader header) throws InvalidSyntaxException {
 		if (header == null)
 			return;
 		for (RequireBundleHeader.Clause clause : header.getClauses()) {
-			RequireBundleRequirement requirement = new RequireBundleRequirement(clause);
+			RequireBundleRequirement requirement = new RequireBundleRequirement(clause, this);
 			String policy = RegionFilter.VISIBLE_REQUIRE_NAMESPACE;
 			String filter = requirement.getDirectives().get(RequireBundleRequirement.DIRECTIVE_FILTER);
 			if (LOGGER.isDebugEnabled())
@@ -1188,11 +1232,11 @@ public class AriesSubsystem implements S
 		}
 	}
 	
-	private static void setImportIsolationPolicy(RegionFilterBuilder builder, RequireCapabilityHeader header) throws InvalidSyntaxException {
+	private void setImportIsolationPolicy(RegionFilterBuilder builder, RequireCapabilityHeader header) throws InvalidSyntaxException {
 		if (header == null)
 			return;
 		for (RequireCapabilityHeader.Clause clause : header.getClauses()) {
-			RequireCapabilityRequirement requirement = new RequireCapabilityRequirement(clause);
+			RequireCapabilityRequirement requirement = new RequireCapabilityRequirement(clause, this);
 			String policy = requirement.getNamespace();
 			String filter = requirement.getDirectives().get(RequireCapabilityRequirement.DIRECTIVE_FILTER);
 			if (LOGGER.isDebugEnabled())
@@ -1201,11 +1245,11 @@ public class AriesSubsystem implements S
 		}
 	}
 	
-	private static void setImportIsolationPolicy(RegionFilterBuilder builder, SubsystemImportServiceHeader header) throws InvalidSyntaxException {
+	private void setImportIsolationPolicy(RegionFilterBuilder builder, SubsystemImportServiceHeader header) throws InvalidSyntaxException {
 		if (header == null)
 			return;
 		for (SubsystemImportServiceHeader.Clause clause : header.getClauses()) {
-			SubsystemImportServiceRequirement requirement = new SubsystemImportServiceRequirement(clause);
+			SubsystemImportServiceRequirement requirement = new SubsystemImportServiceRequirement(clause, this);
 			String policy = RegionFilter.VISIBLE_SERVICE_NAMESPACE;
 			String filter = requirement.getDirectives().get(SubsystemImportServiceRequirement.DIRECTIVE_FILTER);
 			if (LOGGER.isDebugEnabled())

Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SharingPolicyValidator.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SharingPolicyValidator.java?rev=1308154&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SharingPolicyValidator.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SharingPolicyValidator.java Sun Apr  1 16:53:51 2012
@@ -0,0 +1,58 @@
+package org.apache.aries.subsystem.core.internal;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+
+import org.eclipse.equinox.region.Region;
+import org.eclipse.equinox.region.RegionDigraphVisitor;
+import org.eclipse.equinox.region.RegionFilter;
+import org.osgi.resource.Capability;
+
+public class SharingPolicyValidator {
+	private static class Visitor implements RegionDigraphVisitor {
+		private final Map<String, ?> attributes;
+		private final String namespace;
+		private final Collection<Region> visited;
+		
+		public Visitor(String namespace, Map<String, ?> attributes) {
+			this.namespace = namespace;
+			this.attributes = attributes;
+			visited = new HashSet<Region>();
+		}
+		
+		public boolean contains(Region region) {
+			return visited.contains(region);
+		}
+		
+		@Override
+		public void postEdgeTraverse(RegionFilter filter) {
+			// noop
+		}
+
+		@Override
+		public boolean preEdgeTraverse(RegionFilter filter) {
+			return filter.isAllowed(namespace, attributes);
+		}
+
+		@Override
+		public boolean visit(Region region) {
+			visited.add(region);
+			return true;
+		}
+	}
+	
+	private final Region from;
+	private final Region to;
+	
+	public SharingPolicyValidator(Region from, Region to) {
+		this.from = from;
+		this.to = to;
+	}
+	
+	public boolean isValid(Capability capability) {
+		Visitor visitor = new Visitor(capability.getNamespace(), capability.getAttributes());
+		to.visitSubgraph(visitor);
+		return visitor.contains(from);
+	}
+}

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEnvironment.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEnvironment.java?rev=1308154&r1=1308153&r2=1308154&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEnvironment.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemEnvironment.java Sun Apr  1 16:53:51 2012
@@ -22,16 +22,16 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Comparator;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
-import java.util.Set;
 import java.util.SortedSet;
 import java.util.TreeSet;
 
 import org.apache.aries.subsystem.core.Environment;
 import org.apache.aries.subsystem.core.ResourceHelper;
+import org.eclipse.equinox.region.Region;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.namespace.IdentityNamespace;
 import org.osgi.framework.wiring.BundleRevision;
 import org.osgi.resource.Capability;
 import org.osgi.resource.Requirement;
@@ -50,11 +50,21 @@ import org.slf4j.LoggerFactory;
 public class SubsystemEnvironment implements Environment {
 	private static final Logger logger = LoggerFactory.getLogger(SubsystemEnvironment.class);
 	
-	private final Set<Resource> resources = new HashSet<Resource>();
+//	private final Set<Resource> resources = new HashSet<Resource>();
+	private final SharingPolicyValidator validator;
 	private final AriesSubsystem subsystem;
 	
 	public SubsystemEnvironment(AriesSubsystem subsystem) throws IOException, URISyntaxException {
 		this.subsystem = subsystem;
+		Region regionTo = subsystem.getRegion();
+		while (subsystem.getArchive().getSubsystemManifest()
+				.getSubsystemTypeHeader().getProvisionPolicyDirective()
+				.isRejectDependencies()) {
+			subsystem = (AriesSubsystem) subsystem.getParents()
+					.iterator().next();
+		}
+		Region regionFrom = subsystem.getRegion();
+		validator = new SharingPolicyValidator(regionFrom, regionTo);
 	}
 	
 	@Override
@@ -78,23 +88,24 @@ public class SubsystemEnvironment implem
 						return result;
 					}
 				});
-		if (requirement instanceof OsgiIdentityRequirement) {
+		if (requirement instanceof OsgiIdentityRequirement) { 
 			logger.debug("The requirement is an instance of OsgiIdentityRequirement");
 			// TODO Consider returning only the first capability matched by the requirement in this case.
-			// This means we're looking for a content resource.
 			OsgiIdentityRequirement identity = (OsgiIdentityRequirement)requirement;
-			if (subsystem.isFeature()) {
-				// Features share content resources as well as transitive dependencies.
+			// Unscoped subsystems share content resources as well as transitive
+			// dependencies. Scoped subsystems share transitive dependencies as
+			// long as they're in the same region.
+			if (subsystem.isFeature() || identity.isTransitiveDependency()) {
 				findConstituentProviders(requirement, capabilities);
 			}
-			findArchiveProviders(capabilities, identity, !identity.isTransitiveDependency());
-			findRepositoryServiceProviders(capabilities, identity, !identity.isTransitiveDependency());
+			findArchiveProviders(capabilities, identity/*, !identity.isTransitiveDependency()*/);
+			findRepositoryServiceProviders(capabilities, identity/*, !identity.isTransitiveDependency()*/);
 		}
 		else {
 			logger.debug("The requirement is NOT an instance of OsgiIdentityRequirement");
 			// This means we're looking for capabilities satisfying a requirement within a content resource or transitive dependency.
-			findArchiveProviders(capabilities, requirement, false);
-			findRepositoryServiceProviders(capabilities, requirement, false);
+			findArchiveProviders(capabilities, requirement/*, false*/);
+			findRepositoryServiceProviders(capabilities, requirement/*, false*/);
 			// TODO The following is a quick fix to ensure this environment always returns capabilities provided by the system bundle. Needs some more thought.
 			findConstituentProviders(requirement, capabilities);
 		}
@@ -141,10 +152,11 @@ public class SubsystemEnvironment implem
 	}
 	
 	public boolean isContentResource(Resource resource) {
-		logger.debug(LOG_ENTRY, "isContentResource", resource);
-		boolean result = resources.contains(resource);
-		logger.debug(LOG_EXIT, "isContentResource", result);
-		return result;
+//		logger.debug(LOG_ENTRY, "isContentResource", resource);
+//		boolean result = resources.contains(resource);
+//		logger.debug(LOG_EXIT, "isContentResource", result);
+//		return result;
+		return subsystem.getArchive().getSubsystemManifest().getSubsystemContentHeader().contains(resource);
 	}
 
 	@Override
@@ -163,9 +175,9 @@ public class SubsystemEnvironment implem
 			// We only want to return providers from the same region as the subsystem.
 			// Find the one and only one scoped subsystem in the region, which
 			// will be either the current subsystem or one of its parents.
-			while (!(subsystem.isApplication() || subsystem.isComposite())) {
+			do {
 				subsystem = (AriesSubsystem)subsystem.getParents().iterator().next();
-			}
+			} while (!(subsystem.isApplication() || subsystem.isComposite()));
 			// Now search the one and only one scoped parent within the same region
 			// and all children that are also in the same region for a provider.
 			findConstituentProviders(subsystem, requirement, capabilities);
@@ -183,10 +195,21 @@ public class SubsystemEnvironment implem
 	private void findConstituentProviders(AriesSubsystem subsystem, Requirement requirement, Collection<Capability> capabilities) {
 		if (logger.isDebugEnabled())
 			logger.debug(LOG_ENTRY, "findConstituentProviders", new Object[]{subsystem, requirement, capabilities});
+		// Because constituent providers are already provisioned resources, the
+		// sharing policy check must be between the requiring subsystem and the
+		// offering subsystem, not the subsystem the resource would be
+		// provisioned to as in the other methods.
+		SharingPolicyValidator validator = new SharingPolicyValidator(subsystem.getRegion(), this.subsystem.getRegion());
 		for (Resource resource : subsystem.getConstituents()) {
 			logger.debug("Evaluating resource: {}", resource);
 			for (Capability capability : resource.getCapabilities(requirement.getNamespace())) {
 				logger.debug("Evaluating capability: {}", capability);
+				// Filter out capabilities offered by dependencies that will be
+				// or already are provisioned to an out of scope region. This
+				// filtering does not apply to osgi.identity requirements within
+				// the same region.
+				if (!(requirement instanceof OsgiIdentityRequirement) && !validator.isValid(capability))
+					continue;
 				if (ResourceHelper.matches(requirement, capability)) {
 					logger.debug("Adding capability: {}", capability);
 					capabilities.add(capability);
@@ -205,48 +228,52 @@ public class SubsystemEnvironment implem
 		logger.debug(LOG_EXIT, "findConstituentProviders");
 	}
 	
-	private void findArchiveProviders(Collection<Capability> capabilities, Requirement requirement, boolean content) {
+	private void findArchiveProviders(Collection<Capability> capabilities, Requirement requirement/*, boolean content*/) {
 		if (logger.isDebugEnabled())
-			logger.debug(LOG_ENTRY, "findArchiveProviders", new Object[]{capabilities, requirement, content});
+			logger.debug(LOG_ENTRY, "findArchiveProviders", new Object[]{capabilities, requirement/*, content*/});
 		AriesSubsystem subsystem = this.subsystem;
 		logger.debug("Navigating up the parent hierarchy...");
 		while (!subsystem.getParents().isEmpty()) {
 			subsystem = (AriesSubsystem)subsystem.getParents().iterator().next();
 			logger.debug("Next parent is: {}", subsystem);
 		}
-		findArchiveProviders(capabilities, requirement, subsystem, content);
+		findArchiveProviders(capabilities, requirement, subsystem/*, content*/);
 		logger.debug(LOG_EXIT, "findArchiveProviders");
 	}
 	
-	private void findArchiveProviders(Collection<Capability> capabilities, Requirement requirement, AriesSubsystem subsystem, boolean content) {
+	private void findArchiveProviders(Collection<Capability> capabilities, Requirement requirement, AriesSubsystem subsystem/*, boolean content*/) {
 		if (logger.isDebugEnabled())
-			logger.debug(LOG_ENTRY, "findArchiveProviders", new Object[]{capabilities, requirement, subsystem, content});
+			logger.debug(LOG_ENTRY, "findArchiveProviders", new Object[]{capabilities, requirement, subsystem/*, content*/});
 		for (Capability capability : subsystem.getArchive().findProviders(requirement)) {
 			logger.debug("Adding capability: {}", capability);
+			// Filter out capabilities offered by dependencies that will be or
+			// already are provisioned to an out of scope region.
+			if (!requirement.getNamespace().equals(IdentityNamespace.IDENTITY_NAMESPACE) && !isContentResource(capability.getResource()) && !validator.isValid(capability))
+				continue;
 			capabilities.add(capability);
-			if (content) {
-				Resource resource = capability.getResource();
-				logger.debug("Adding content resource: {}", resource);
-				resources.add(resource);
-			}
+//			if (content) {
+//				Resource resource = capability.getResource();
+//				logger.debug("Adding content resource: {}", resource);
+//				resources.add(resource);
+//			}
 		}
-		findArchiveProviders(capabilities, requirement, subsystem.getChildren(), content);
+		findArchiveProviders(capabilities, requirement, subsystem.getChildren()/*, content*/);
 		logger.debug(LOG_EXIT, "findArchiveProviders");
 	}
 	
-	private void findArchiveProviders(Collection<Capability> capabilities, Requirement requirement, Collection<Subsystem> children, boolean content) {
+	private void findArchiveProviders(Collection<Capability> capabilities, Requirement requirement, Collection<Subsystem> children/*, boolean content*/) {
 		if (logger.isDebugEnabled())
-			logger.debug(LOG_ENTRY, "findArchiveProviders", new Object[]{capabilities, requirement, children, content});
+			logger.debug(LOG_ENTRY, "findArchiveProviders", new Object[]{capabilities, requirement, children/*, content*/});
 		for (Subsystem child : children) {
 			logger.debug("Evaluating child subsystem: {}", child);
-			findArchiveProviders(capabilities, requirement, (AriesSubsystem)child, content);
+			findArchiveProviders(capabilities, requirement, (AriesSubsystem)child/*, content*/);
 		}
 		logger.debug(LOG_EXIT, "findArchiveProviders");
 	}
 	
-	private void findRepositoryServiceProviders(Collection<Capability> capabilities, Requirement requirement, boolean content) {
+	private void findRepositoryServiceProviders(Collection<Capability> capabilities, Requirement requirement/*, boolean content*/) {
 		if (logger.isDebugEnabled())
-			logger.debug(LOG_ENTRY, "findRepositoryServiceProviders", new Object[]{capabilities, requirement, content});
+			logger.debug(LOG_ENTRY, "findRepositoryServiceProviders", new Object[]{capabilities, requirement/*, content*/});
 		Collection<Repository> repositories = Activator.getInstance().getServiceProvider().getServices(Repository.class);
 		for (Repository repository : repositories) {
 			logger.debug("Evaluating repository: {}", repository);
@@ -255,12 +282,16 @@ public class SubsystemEnvironment implem
 			if (caps != null) {
 				for (Capability capability : caps) {
 					logger.debug("Adding capability: {}", capability);
+					// Filter out capabilities offered by dependencies that will be or
+					// already are provisioned to an out of scope region.
+					if (!requirement.getNamespace().equals(IdentityNamespace.IDENTITY_NAMESPACE) && !isContentResource(capability.getResource()) && !validator.isValid(capability))
+						continue;
 					capabilities.add(capability);
-					if (content) {
-						Resource resource = capability.getResource();
-						logger.debug("Adding content resource: {}", resource);
-						resources.add(resource);
-					}
+//					if (content) {
+//						Resource resource = capability.getResource();
+//						logger.debug("Adding content resource: {}", resource);
+//						resources.add(resource);
+//					}
 				}
 			}
 		}

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemServiceRegistrar.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemServiceRegistrar.java?rev=1308154&r1=1308153&r2=1308154&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemServiceRegistrar.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemServiceRegistrar.java Sun Apr  1 16:53:51 2012
@@ -32,7 +32,7 @@ public class SubsystemServiceRegistrar {
 	public synchronized void unregister(Subsystem subsystem) {
 		ServiceRegistration<Subsystem> registration = map.remove(subsystem);
 		if (registration == null)
-			throw new IllegalArgumentException("Subsystem '" + subsystem + "' is not registered");
+			throw new IllegalStateException("Subsystem '" + subsystem + "' is not registered");
 		registration.unregister();
 	}
 	
@@ -47,7 +47,7 @@ public class SubsystemServiceRegistrar {
 	public synchronized void update(Subsystem subsystem) {
 		ServiceRegistration<Subsystem> registration = map.get(subsystem);
 		if (registration == null)
-			throw new IllegalArgumentException("Subsystem '" + subsystem + "' is not registered");
+			throw new IllegalStateException("Subsystem '" + subsystem + "' is not registered");
 		Dictionary<String, Object> properties = properties(subsystem);
 		registration.setProperties(properties);
 	}

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemUri.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemUri.java?rev=1308154&r1=1308153&r2=1308154&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemUri.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemUri.java Sun Apr  1 16:53:51 2012
@@ -13,16 +13,19 @@
  */
 package org.apache.aries.subsystem.core.internal;
 
+import java.io.UnsupportedEncodingException;
 import java.net.MalformedURLException;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
+import java.net.URLEncoder;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.apache.aries.subsystem.core.archive.SubsystemSymbolicNameHeader;
 import org.apache.aries.subsystem.core.archive.SubsystemVersionHeader;
 import org.osgi.framework.Version;
+import org.osgi.service.subsystem.SubsystemConstants;
 
 public class SubsystemUri {
 	private static final String REGEXP = "([^=]*)=([^&]*)&?";
@@ -56,6 +59,16 @@ public class SubsystemUri {
 		this.version = version;
 	}
 	
+	public SubsystemUri(String symbolicName, Version version, URL url) {
+		// TODO symbolicName should conform to OSGi grammar.
+		if (symbolicName == null || symbolicName.length() == 0)
+			throw new IllegalArgumentException(
+					"Missing required parameter: symbolicName");
+		this.symbolicName = symbolicName;
+		this.version = version;
+		this.url = url;
+	}
+	
 	public String getSymbolicName() {
 		return symbolicName;
 	}
@@ -67,4 +80,21 @@ public class SubsystemUri {
 	public Version getVersion() {
 		return version;
 	}
+	
+	public String toString() {
+		StringBuilder builder = new StringBuilder("subsystem://");
+		if (url != null) {
+			try {
+				builder.append(URLEncoder.encode(url.toString(), "UTF-8"));
+			} catch (UnsupportedEncodingException e) {
+				builder.append(URLEncoder.encode(url.toString()));
+			}
+		}
+		builder.append('?').append(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME)
+				.append('=').append(symbolicName);
+		if (version != null)
+			builder.append('&').append(SubsystemConstants.SUBSYSTEM_VERSION)
+					.append('=').append(version);
+		return builder.toString();
+	}
 }

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=1308154&r1=1308153&r2=1308154&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 Apr  1 16:53:51 2012
@@ -75,11 +75,11 @@ public class BundleResource implements R
 		RequireCapabilityHeader rch = (RequireCapabilityHeader)manifest.getHeader(RequireCapabilityHeader.NAME);
 		if (rch != null)
 			for (RequireCapabilityHeader.Clause clause : rch.getClauses())
-				requirements.add(new RequireCapabilityRequirement(clause));
+				requirements.add(new RequireCapabilityRequirement(clause, this));
 		RequireBundleHeader rbh = (RequireBundleHeader)manifest.getHeader(RequireBundleHeader.NAME);
 		if (rbh != null)
 			for (RequireBundleHeader.Clause clause : rbh.getClauses())
-				requirements.add(new RequireBundleRequirement(clause));
+				requirements.add(new RequireBundleRequirement(clause, this));
 		// TODO The osgi.wiring.bundle capability should not be provided for fragments. Nor should the host capability.
 		BundleSymbolicNameHeader bsnh = (BundleSymbolicNameHeader)manifest.getHeader(BundleSymbolicNameHeader.NAME);
 		BundleVersionHeader bvh = (BundleVersionHeader)manifest.getHeader(BundleVersionHeader.NAME);

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemFileResource.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemFileResource.java?rev=1308154&r1=1308153&r2=1308154&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemFileResource.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemFileResource.java Sun Apr  1 16:53:51 2012
@@ -8,92 +8,62 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
-import java.util.Map.Entry;
 import java.util.jar.Manifest;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import org.apache.aries.subsystem.core.archive.Header;
-import org.apache.aries.subsystem.core.archive.HeaderFactory;
+import org.apache.aries.subsystem.core.archive.DeploymentManifest;
+import org.apache.aries.subsystem.core.archive.ImportPackageHeader;
+import org.apache.aries.subsystem.core.archive.RequireBundleHeader;
+import org.apache.aries.subsystem.core.archive.RequireCapabilityHeader;
 import org.apache.aries.subsystem.core.archive.SubsystemContentHeader;
 import org.apache.aries.subsystem.core.archive.SubsystemManifest;
 import org.apache.aries.subsystem.core.archive.SubsystemSymbolicNameHeader;
 import org.apache.aries.subsystem.core.archive.SubsystemTypeHeader;
 import org.apache.aries.subsystem.core.archive.SubsystemVersionHeader;
 import org.apache.aries.subsystem.core.internal.Activator;
-import org.apache.aries.subsystem.core.internal.OsgiIdentityCapability;
 import org.apache.aries.util.filesystem.FileSystem;
 import org.apache.aries.util.filesystem.IDirectory;
 import org.apache.aries.util.filesystem.IFile;
 import org.apache.aries.util.manifest.ManifestProcessor;
+import org.osgi.framework.Version;
+import org.osgi.framework.namespace.BundleNamespace;
+import org.osgi.framework.namespace.PackageNamespace;
 import org.osgi.resource.Capability;
 import org.osgi.resource.Requirement;
 import org.osgi.resource.Resource;
 import org.osgi.service.repository.RepositoryContent;
 import org.osgi.service.subsystem.SubsystemConstants;
+import org.osgi.service.subsystem.SubsystemException;
 
 public class SubsystemFileResource implements Resource, RepositoryContent {
 	private static final String REGEX = "([^@]+)(?:@(.+))?.esa"; // TODO Add .esa to constants.
 	private static final Pattern PATTERN = Pattern.compile(REGEX);
 	
 	private final List<Capability> capabilities;
+	private final DeploymentManifest deploymentManifest;
 	private final IDirectory directory;
 	private final File file;
 	private final IFile iFile;
 	private final String location;
 	private final List<Requirement> requirements;
+	private final Collection<Resource> resources;
+	private final SubsystemManifest subsystemManifest;
 	
 	public SubsystemFileResource(File content) throws IOException {
 		this(FileSystem.getFSRoot(content), content, null);
 	}
 	
 	private SubsystemFileResource(IDirectory directory, File file, IFile iFile) throws IOException {
-		String fileName = file == null ? iFile.getName() : file.getName();
 		this.directory = directory;
 		this.file = file;
 		this.iFile = iFile;
-		Manifest manifest = ManifestProcessor.obtainManifestFromAppDir(directory, "OSGI-INF/DEPLOYMENT.MF");
-		if (manifest == null)
-			manifest = ManifestProcessor.obtainManifestFromAppDir(directory, "OSGI-INF/SUBSYSTEM.MF");
-		
-		String symbolicName = manifest == null ? null : manifest.getMainAttributes().getValue(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME);
-		Matcher matcher = PATTERN.matcher(fileName);
-		if (symbolicName == null) {
-			if (!matcher.matches())
-				throw new IllegalArgumentException("No syi guess the only rulembolic name");
-			symbolicName = new SubsystemSymbolicNameHeader(matcher.group(1)).getSymbolicName();
-		}
-		SubsystemManifest.Builder builder = new SubsystemManifest.Builder(symbolicName);
-		if (manifest != null)
-			for (Entry<Object, Object> entry : manifest.getMainAttributes().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 == SubsystemVersionHeader.DEFAULT && matcher.matches()) {
-			String group = matcher.group(2);
-			if (group != null)
-				version = new SubsystemVersionHeader(group);
-		}
-		List<Capability> capabilities = subsystemManifest.toCapabilities(this);
-		capabilities.add(new OsgiIdentityCapability(this, symbolicName, version.getVersion(), type.getType()));
-		this.capabilities = Collections.unmodifiableList(capabilities);
-		if (type.getType().equals(SubsystemTypeHeader.TYPE_APPLICATION) ||
-				type.getType().equals(SubsystemTypeHeader.TYPE_FEATURE))
-			this.requirements = computeDependencies(subsystemManifest.getSubsystemContentHeader());
-		else
-			this.requirements = Collections.unmodifiableList(subsystemManifest.toRequirements(this));
-		location = "subsystem://?" + SubsystemConstants.SUBSYSTEM_SYMBOLICNAME + '=' + symbolicName + '&' + SubsystemConstants.SUBSYSTEM_VERSION + '=' + version.getVersion();
+		resources = computeResources();
+		deploymentManifest = generateDeploymentManifest();
+		subsystemManifest = generateSubsystemManifest();
+		capabilities = subsystemManifest.toCapabilities(this);
+		requirements = computeDependencies();
+		location = computeLocation();
 	}
 	
 	@Override
@@ -121,6 +91,10 @@ public class SubsystemFileResource imple
 	public String getLocation() {
 		return location;
 	}
+	
+	public DeploymentManifest getDeploymentManifest() {
+		return deploymentManifest;
+	}
 
 	@Override
 	public List<Requirement> getRequirements(String namespace) {
@@ -134,10 +108,27 @@ public class SubsystemFileResource imple
 		return result;
 	}
 	
-	private List<Requirement> computeDependencies(SubsystemContentHeader header) throws IOException {
+	public Collection<Resource> getResources() {
+		return resources;
+	}
+	
+	public SubsystemManifest getSubsystemManifest() {
+		return subsystemManifest;
+	}
+	
+	private List<Requirement> computeDependencies() throws IOException {
+		SubsystemTypeHeader type = subsystemManifest.getSubsystemTypeHeader();
+		if (SubsystemTypeHeader.TYPE_APPLICATION.equals(type.getType()))
+			return computeDependenciesForApplication();
+		return subsystemManifest.toRequirements(this);
+	}
+	
+	private List<Requirement> computeDependenciesForApplication() throws IOException {
+		SubsystemContentHeader header = subsystemManifest.getSubsystemContentHeader();
 		if (header == null)
 			return Collections.emptyList();
-		LocalRepository localRepo = new LocalRepository(computeResources());
+		// TODO Need the system repository in here. Preferred provider as well?
+		LocalRepository localRepo = new LocalRepository(resources);
 		RepositoryServiceRepository serviceRepo = new RepositoryServiceRepository(Activator.getInstance().getBundleContext());
 		CompositeRepository compositeRepo = new CompositeRepository(localRepo, serviceRepo);
 		List<Requirement> requirements = header.toRequirements();
@@ -151,6 +142,59 @@ public class SubsystemFileResource imple
 		return new DependencyCalculator(resources).calculateDependencies();
 	}
 	
+	private ImportPackageHeader computeImportPackageHeaderForApplication() {
+		if (requirements.isEmpty())
+			return null;
+		ArrayList<ImportPackageHeader.Clause> clauses = new ArrayList<ImportPackageHeader.Clause>(requirements.size());
+		for (Requirement requirement : requirements) {
+			if (!PackageNamespace.PACKAGE_NAMESPACE.equals(requirement.getNamespace()))
+				continue;
+			clauses.add(new ImportPackageHeader.Clause(requirement));
+		}
+		if (clauses.isEmpty())
+			return null;
+		clauses.trimToSize();
+		return new ImportPackageHeader(clauses);
+	}
+	
+	private String computeLocation() {
+		return "subsystem://?" + SubsystemConstants.SUBSYSTEM_SYMBOLICNAME
+				+ '=' 
+				+ subsystemManifest.getSubsystemSymbolicNameHeader().getSymbolicName() 
+				+ '&' + SubsystemConstants.SUBSYSTEM_VERSION + '='
+				+ subsystemManifest.getSubsystemVersionHeader().getVersion();
+	}
+	
+	private RequireBundleHeader computeRequireBundleHeaderForApplication() {
+		if (requirements.isEmpty())
+			return null;
+		ArrayList<RequireBundleHeader.Clause> clauses = new ArrayList<RequireBundleHeader.Clause>(requirements.size());
+		for (Requirement requirement : requirements) {
+			if (!BundleNamespace.BUNDLE_NAMESPACE.equals(requirement.getNamespace()))
+				continue;
+			clauses.add(new RequireBundleHeader.Clause(requirement));
+		}
+		if (clauses.isEmpty())
+			return null;
+		clauses.trimToSize();
+		return new RequireBundleHeader(clauses);
+	}
+	
+	private RequireCapabilityHeader computeRequireCapabilityHeaderForApplication() {
+		if (requirements.isEmpty())
+			return null;
+		ArrayList<RequireCapabilityHeader.Clause> clauses = new ArrayList<RequireCapabilityHeader.Clause>();
+		for (Requirement requirement : requirements) {
+			if (requirement.getNamespace().startsWith("osgi."))
+				continue;
+			clauses.add(new RequireCapabilityHeader.Clause(requirement));
+		}
+		if (clauses.isEmpty())
+			return null;
+		clauses.trimToSize();
+		return new RequireCapabilityHeader(clauses);
+	}
+	
 	private Collection<Resource> computeResources() throws IOException {
 		List<IFile> files = directory.listFiles();
 		if (files.isEmpty())
@@ -166,4 +210,97 @@ public class SubsystemFileResource imple
 		result.trimToSize();
 		return result;
 	}
+	
+	private void fillInSubsystemManifestContent(SubsystemManifest.Builder builder) {
+		builder.content(resources);
+	}
+	
+	private SubsystemManifest fillInSubsystemManifestDefaults(SubsystemManifest manifest) {
+		SubsystemManifest.Builder builder = new SubsystemManifest.Builder().manifest(manifest);
+		fillInSubsystemManifestSymbolicNameAndVersionFromFileName(manifest, builder);
+		if (manifest.getSubsystemContentHeader() == null)
+			fillInSubsystemManifestContent(builder);
+		if (manifest.getSubsystemTypeHeader().getType().equals(SubsystemTypeHeader.TYPE_APPLICATION))
+			fillInSubsystemManifestForApplication(builder);
+		return builder.build();
+	}
+	
+	private void fillInSubsystemManifestForApplication(SubsystemManifest.Builder builder) {
+		builder
+		.header(computeImportPackageHeaderForApplication())
+		.header(computeRequireBundleHeaderForApplication())
+		.header(computeRequireCapabilityHeaderForApplication());
+	}
+	
+	private void fillInSubsystemManifestSymbolicNameAndVersionFromFileName(
+			SubsystemManifest manifest, 
+			SubsystemManifest.Builder builder) {
+		String fileName = file == null ? iFile.getName() : file.getName();
+		Matcher matcher = PATTERN.matcher(fileName);
+		if (!matcher.matches())
+			return;
+		fillInSubsystemManifestSymbolicName(builder, manifest.getSubsystemSymbolicNameHeader(), matcher.group(1));
+		fillInSubsystemManifestVersion(builder, manifest.getSubsystemVersionHeader(), matcher.group(2));
+	}
+	
+	private void fillInSubsystemManifestSymbolicName(
+			SubsystemManifest.Builder builder,
+			SubsystemSymbolicNameHeader header,
+			String symbolicName) {
+		if (header == null)
+			builder.symbolicName(symbolicName);
+	}
+	
+	private void fillInSubsystemManifestVersion(
+			SubsystemManifest.Builder builder,
+			SubsystemVersionHeader header,
+			String version) {
+		if (version == null)
+			return;
+		fillInSubsystemManifestVersion(builder, header, Version.parseVersion(version));
+	}
+	
+	private void fillInSubsystemManifestVersion(
+			SubsystemManifest.Builder builder,
+			SubsystemVersionHeader header,
+			Version version) {
+		if (header.getVersion().equals(Version.emptyVersion))
+			builder.version(version);
+	}
+	
+	private SubsystemManifest generateDefaultSubsystemManifest() {
+		return new SubsystemManifest(generateDefaultSymbolicName(), null, resources);
+	}
+	
+	private String generateDefaultSymbolicName() {
+		String fileName = file == null ? iFile.getName() : file.getName();
+		Matcher matcher = PATTERN.matcher(fileName);
+		if (!matcher.matches())
+			throw new IllegalArgumentException("No symbolic name");
+		return matcher.group(1);
+	}
+	
+	private DeploymentManifest generateDeploymentManifest() throws IOException {
+		Manifest manifest = ManifestProcessor.obtainManifestFromAppDir(directory, "OSGI-INF/DEPLOYMENT.MF");
+		if (manifest == null)
+			return null;
+		return new DeploymentManifest(manifest);
+	}
+	
+	private SubsystemManifest generateExistingSubsystemManifest() throws IOException {
+		Manifest manifest = ManifestProcessor.obtainManifestFromAppDir(directory, "OSGI-INF/SUBSYSTEM.MF");
+		if (manifest == null)
+			return null;
+		return new SubsystemManifest(manifest);
+	}
+	
+	private SubsystemManifest generateSubsystemManifest() throws IOException {
+		SubsystemManifest result = generateExistingSubsystemManifest();
+		if (result == null)
+			result = generateDefaultSubsystemManifest();
+		result = fillInSubsystemManifestDefaults(result);
+		if (result.getSubsystemSymbolicNameHeader() == null)
+			throw new SubsystemException("Missing symbolic name");
+		return result;
+	}
 }

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=1308154&r1=1308153&r2=1308154&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 Apr  1 16:53:51 2012
@@ -69,7 +69,7 @@ public class SubsystemStreamResource imp
 				throw new IllegalArgumentException("No symbolic name");
 			symbolicName = uri.getSymbolicName();
 		}
-		SubsystemManifest.Builder builder = new SubsystemManifest.Builder(symbolicName);
+		SubsystemManifest.Builder builder = new SubsystemManifest.Builder().symbolicName(symbolicName);
 		if (manifest != null)
 			for (Entry<Object, Object> entry : manifest.getMainAttributes().entrySet()) {
 				String key = String.valueOf(entry.getKey());

Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/ApplicationResource.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/ApplicationResource.java?rev=1308154&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/ApplicationResource.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/ApplicationResource.java Sun Apr  1 16:53:51 2012
@@ -0,0 +1,13 @@
+package org.apache.aries.subsystem.core.resource.tmp;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+
+import org.apache.aries.subsystem.core.archive.SubsystemManifest;
+import org.apache.aries.util.filesystem.IDirectory;
+
+public class ApplicationResource extends SubsystemResource {
+	ApplicationResource(Location location, IDirectory directory, SubsystemManifest manifest) throws IOException, URISyntaxException {
+		super(location, directory, manifest);
+	}
+}

Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/BundleResource.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/BundleResource.java?rev=1308154&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/BundleResource.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/BundleResource.java Sun Apr  1 16:53:51 2012
@@ -0,0 +1,27 @@
+package org.apache.aries.subsystem.core.resource.tmp;
+
+import java.util.List;
+
+import org.apache.aries.util.filesystem.IFile;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+
+public class BundleResource implements Resource {
+	public BundleResource(IFile file) {
+		
+	}
+
+	@Override
+	public List<Capability> getCapabilities(String arg0) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public List<Requirement> getRequirements(String arg0) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+}

Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/CompositeResource.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/CompositeResource.java?rev=1308154&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/CompositeResource.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/CompositeResource.java Sun Apr  1 16:53:51 2012
@@ -0,0 +1,26 @@
+package org.apache.aries.subsystem.core.resource.tmp;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.List;
+
+import org.apache.aries.subsystem.core.archive.SubsystemManifest;
+import org.apache.aries.util.filesystem.IDirectory;
+import org.osgi.resource.Requirement;
+
+public class CompositeResource extends SubsystemResource {
+	public CompositeResource(Location location, IDirectory directory,
+			SubsystemManifest manifest) throws IOException, URISyntaxException {
+		super(location, directory, manifest);
+	}
+	
+	@Override
+	protected List<Requirement> computeRequirements(SubsystemManifest manifest) {
+		return manifest.toRequirements(this);
+	}
+	
+	@Override
+	protected SubsystemManifest computeSubsystemManifestAfterRequirements(SubsystemManifest manifest) {
+		return manifest;
+	}
+}

Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/DeploymentManifest.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/DeploymentManifest.java?rev=1308154&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/DeploymentManifest.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/DeploymentManifest.java Sun Apr  1 16:53:51 2012
@@ -0,0 +1,9 @@
+package org.apache.aries.subsystem.core.resource.tmp;
+
+import org.apache.aries.util.filesystem.IFile;
+
+public class DeploymentManifest {
+	public DeploymentManifest(IFile file) {
+		
+	}
+}

Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/FeatureResource.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/FeatureResource.java?rev=1308154&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/FeatureResource.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/tmp/FeatureResource.java Sun Apr  1 16:53:51 2012
@@ -0,0 +1,14 @@
+package org.apache.aries.subsystem.core.resource.tmp;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+
+import org.apache.aries.subsystem.core.archive.SubsystemManifest;
+import org.apache.aries.util.filesystem.IDirectory;
+
+public class FeatureResource extends SubsystemResource {
+	public FeatureResource(Location location, IDirectory directory,
+			SubsystemManifest manifest) throws IOException, URISyntaxException {
+		super(location, directory, manifest);
+	}
+}