Return-Path: X-Original-To: apmail-aries-commits-archive@www.apache.org Delivered-To: apmail-aries-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 051CA9F86 for ; Sun, 18 Mar 2012 23:50:01 +0000 (UTC) Received: (qmail 88064 invoked by uid 500); 18 Mar 2012 23:50:01 -0000 Delivered-To: apmail-aries-commits-archive@aries.apache.org Received: (qmail 87968 invoked by uid 500); 18 Mar 2012 23:50:01 -0000 Mailing-List: contact commits-help@aries.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@aries.apache.org Delivered-To: mailing list commits@aries.apache.org Received: (qmail 87952 invoked by uid 99); 18 Mar 2012 23:50:00 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 18 Mar 2012 23:50:00 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 18 Mar 2012 23:49:56 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 7D7AC2388860; Sun, 18 Mar 2012 23:49:36 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: 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/... Date: Sun, 18 Mar 2012 23:49:35 -0000 To: commits@aries.apache.org From: jwross@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120318234936.7D7AC2388860@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 extends Header { + List 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(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 provisionResource = new HashSet(); 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 { +public class ExportPackageHeader implements CapabilityHeader { 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 toCapabilities(Resource resource) { - Collection result = new ArrayList(); + @Override + public List toCapabilities(Resource resource) { + List result = new ArrayList(); 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 { +public class ImportPackageHeader implements RequirementHeader { 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 getRequirements(Resource resource) { + @Override + public String getValue() { + return toString(); + } + + @Override + public List toRequirements(Resource resource) { Collection clauses = getClauses(); - Collection result = new HashSet(clauses.size()); + List result = new ArrayList(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 { +public class ProvideCapabilityHeader implements CapabilityHeader { 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 toCapabilities(Resource resource) { + List result = new ArrayList(); + 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 { +public class RequireBundleHeader implements RequirementHeader { 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 toRequirements(Resource resource) { + List requirements = new ArrayList(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 { +public class RequireCapabilityHeader implements RequirementHeader { 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 toRequirements(Resource resource) { + List requirements = new ArrayList(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 extends Header { + List 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 { +public class SubsystemExportServiceHeader implements CapabilityHeader { 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 toCapabilities(Resource resource) { + List result = new ArrayList(); + 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 { +public class SubsystemImportServiceHeader implements RequirementHeader { 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 toRequirements(Resource resource) { + List requirements = new ArrayList(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 toCapabilities(Resource resource) { + ArrayList requirements = new ArrayList(); + for (Header header : headers.values()) + if (header instanceof CapabilityHeader) + requirements.addAll(((CapabilityHeader)header).toCapabilities(resource)); + requirements.trimToSize(); + return requirements; + } + + public List toRequirements(Resource resource) { + ArrayList requirements = new ArrayList(); + 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 locationToSubsystem = Collections.synchronizedMap(new HashMap()); + private static final ResourceReferences resourceReferences = new ResourceReferences(); private static final Map> resourceToSubsystems = Collections.synchronizedMap(new HashMap>()); static synchronized Collection 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 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 result = archive.getSubsystemManifest().toCapabilities(this); + result.add(capability); + return result; + } + List result = archive.getSubsystemManifest().toCapabilities(this); + for (Iterator 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 getRequirements(String namespace) { - return Collections.emptyList(); + if (namespace == null) + return archive.getSubsystemManifest().toRequirements(this); + List result = archive.getSubsystemManifest().toRequirements(this); + for (Iterator 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> resourceToSubsystems = new HashMap>(); + private final Map> subsystemToResources = new HashMap>(); + + public synchronized void addReference(Subsystem subsystem, Resource resource) { + addSubsystemToResource(subsystem, resource); + addResourceToSubsystem(subsystem, resource); + } + + public synchronized Collection getResources(Subsystem subsystem) { + Collection result = subsystemToResources.get(subsystem); + if (result == null) + result = Collections.emptyList(); + return Collections.unmodifiableCollection(new ArrayList(result)); + } + + public synchronized Collection getSubsystems(Resource resource) { + Collection result = resourceToSubsystems.get(resource); + if (result == null) + result = Collections.emptyList(); + return Collections.unmodifiableCollection(new ArrayList(result)); + } + + public synchronized void removeReference(Subsystem subsystem, Resource resource) { + removeResourceToSubsystem(subsystem, resource); + removeSubsystemToResource(subsystem, resource); + } + + private void addResourceToSubsystem(Subsystem subsystem, Resource resource) { + Set subsystems = resourceToSubsystems.get(resource); + if (subsystems == null) { + subsystems = new HashSet(); + resourceToSubsystems.put(resource, subsystems); + } + subsystems.add(subsystem); + } + + private void addSubsystemToResource(Subsystem subsystem, Resource resource) { + Set resources = subsystemToResources.get(subsystem); + if (resources == null) { + resources = new HashSet(); + subsystemToResources.put(subsystem, resources); + } + resources.add(resource); + } + + private void removeResourceToSubsystem(Subsystem subsystem, Resource resource) { + Set 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 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 capabilities; private final ICloseableDirectory directory; + private final List 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 capabilities = new ArrayList(1); - capabilities.add(new OsgiIdentityCapability(this, symbolicName, version, type)); + SubsystemManifest.Builder builder = new SubsystemManifest.Builder(symbolicName); + for (Entry 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 capabilities; + List 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 getCapabilities(String namespace) { - if (namespace == null || IdentityNamespace.IDENTITY_NAMESPACE.equals(namespace)) + if (namespace == null) return capabilities; - return Collections.emptyList(); + ArrayList result = new ArrayList(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 getRequirements(String namespace) { - return Collections.emptyList(); + if (namespace == null) + return requirements; + ArrayList result = new ArrayList(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 attributes = new HashMap(); + 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 headers = new HashMap(); + headers.put(Constants.IMPORT_PACKAGE, "x"); + createBundle(BUNDLE_A, headers); + } + + private static void createBundleB() throws IOException { + Map headers = new HashMap(); + 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 children = new ArrayList(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))) {