aries-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dav...@apache.org
Subject svn commit: r1642910 [2/3] - in /aries/trunk/subsystem: subsystem-api/ subsystem-api/src/main/java/org/apache/aries/subsystem/ subsystem-bundle/ subsystem-core/ subsystem-core/src/main/java/org/apache/aries/subsystem/core/content/ subsystem-core/src/ma...
Date Tue, 02 Dec 2014 15:38:39 GMT
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceInstaller.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceInstaller.java?rev=1642910&r1=1642909&r2=1642910&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceInstaller.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceInstaller.java Tue Dec  2 15:38:38 2014
@@ -13,8 +13,10 @@
  */
 package org.apache.aries.subsystem.core.internal;
 
+import org.apache.aries.subsystem.ContentHandler;
 import org.apache.aries.subsystem.core.archive.DeployedContentHeader;
 import org.apache.aries.subsystem.core.archive.DeploymentManifest;
+import org.osgi.framework.ServiceReference;
 import org.osgi.framework.namespace.IdentityNamespace;
 import org.osgi.resource.Resource;
 import org.osgi.service.coordinator.Coordination;
@@ -27,28 +29,32 @@ public abstract class ResourceInstaller 
 		String type = ResourceHelper.getTypeAttribute(resource);
 		if (SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION.equals(type)
 				|| SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE.equals(type)
-				|| SubsystemConstants.SUBSYSTEM_TYPE_FEATURE.equals(type))
+				|| SubsystemConstants.SUBSYSTEM_TYPE_FEATURE.equals(type)) {
 			return new SubsystemResourceInstaller(coordination, resource, subsystem);
-		else if (IdentityNamespace.TYPE_BUNDLE.equals(type) || IdentityNamespace.TYPE_FRAGMENT.equals(type))
+		} else if (IdentityNamespace.TYPE_BUNDLE.equals(type) || IdentityNamespace.TYPE_FRAGMENT.equals(type)) {
 			return new BundleResourceInstaller(coordination, resource, subsystem);
-		else if (Constants.ResourceTypeSynthesized.equals(type)) {
+		} else if (Constants.ResourceTypeSynthesized.equals(type)) {
 			return new ResourceInstaller(coordination, resource, subsystem) {
-				
 				@Override
 				public Resource install() throws Exception {
 					// do nothing;
 					return resource;
 				}
 			};
+		} else {
+		    ServiceReference<ContentHandler> handlerRef = CustomResources.getCustomContentHandler(subsystem, type);
+		    if (handlerRef != null)
+		        return new CustomResourceInstaller(coordination, resource, type, subsystem, handlerRef);
+
 		}
-			throw new SubsystemException("No installer exists for resource type: " + type);
+		throw new SubsystemException("No installer exists for resource type: " + type);
 	}
-	
-	protected final Coordination coordination;
+
+    protected final Coordination coordination;
 	protected final BasicSubsystem provisionTo;
 	protected final Resource resource;
 	protected final BasicSubsystem subsystem;
-	
+
 	public ResourceInstaller(Coordination coordination, Resource resource, BasicSubsystem subsystem) {
 		this.coordination = coordination;
 		this.resource = resource;
@@ -62,9 +68,9 @@ public abstract class ResourceInstaller 
 		else
 			provisionTo = subsystem;
 	}
-	
+
 	public abstract Resource install() throws Exception;
-	
+
 	protected void addConstituent(final Resource resource) {
 		// Don't let a resource become a constituent of itself.
 		if (provisionTo == null || resource.equals(provisionTo))
@@ -82,7 +88,7 @@ public abstract class ResourceInstaller 
 			}
 		});
 	}
-	
+
 	protected void addReference(final Resource resource) {
 		// Don't let a resource reference itself.
 		if (resource.equals(subsystem))
@@ -106,19 +112,19 @@ public abstract class ResourceInstaller 
 			});
 		}
 	}
-	
+
 	protected String getLocation() {
 		return provisionTo.getLocation() + "!/" + ResourceHelper.getLocation(resource);
 	}
-	
+
 	protected boolean isContent() {
 		return Utils.isContent(subsystem, resource);
 	}
-	
+
 	protected boolean isDependency() {
 		return Utils.isDependency(subsystem, resource);
 	}
-	
+
 	protected boolean isReferencedProvisionTo() {
 		DeploymentManifest manifest = subsystem.getDeploymentManifest();
 		if (manifest != null) {
@@ -130,7 +136,7 @@ public abstract class ResourceInstaller 
 			return isReferencedSubsystem();
 		return false;
 	}
-	
+
 	protected boolean isReferencedSubsystem() {
 		DeploymentManifest manifest = subsystem.getDeploymentManifest();
 		if (manifest != null) {

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceUninstaller.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceUninstaller.java?rev=1642910&r1=1642909&r2=1642910&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceUninstaller.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/ResourceUninstaller.java Tue Dec  2 15:38:38 2014
@@ -13,7 +13,9 @@
  */
 package org.apache.aries.subsystem.core.internal;
 
+import org.apache.aries.subsystem.ContentHandler;
 import org.apache.aries.subsystem.core.archive.ProvisionResourceHeader;
+import org.osgi.framework.ServiceReference;
 import org.osgi.framework.namespace.IdentityNamespace;
 import org.osgi.framework.wiring.BundleRevision;
 import org.osgi.resource.Resource;
@@ -24,31 +26,37 @@ import org.slf4j.LoggerFactory;
 
 public abstract class ResourceUninstaller {
 	private static final Logger logger = LoggerFactory.getLogger(ResourceUninstaller.class);
-	
+
 	public static ResourceUninstaller newInstance(Resource resource, BasicSubsystem subsystem) {
 		String type = ResourceHelper.getTypeAttribute(resource);
 		if (SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION.equals(type)
 				|| SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE.equals(type)
-				|| SubsystemConstants.SUBSYSTEM_TYPE_FEATURE.equals(type))
+				|| SubsystemConstants.SUBSYSTEM_TYPE_FEATURE.equals(type)) {
 			return new SubsystemResourceUninstaller(resource, subsystem);
-		else if (IdentityNamespace.TYPE_BUNDLE.equals(type) || IdentityNamespace.TYPE_FRAGMENT.equals(type))
+		} else if (IdentityNamespace.TYPE_BUNDLE.equals(type) || IdentityNamespace.TYPE_FRAGMENT.equals(type)) {
 			return new BundleResourceUninstaller(resource, subsystem);
-		else
-			throw new SubsystemException("No uninstaller exists for resource type: " + type);
+		} else {
+		    ServiceReference<ContentHandler> handlerRef = CustomResources.getCustomContentHandler(subsystem, type);
+		    if (handlerRef != null) {
+		        return new CustomResourceUninstaller(resource, type, subsystem, handlerRef);
+		    } else {
+		        throw new SubsystemException("No uninstaller exists for resource type: " + type);
+		    }
+		}
 	}
-	
+
 	protected static void removeConstituent(BasicSubsystem subsystem, Resource resource) {
 		Activator.getInstance().getSubsystems().removeConstituent(subsystem, resource);
 	}
-	
+
 	protected static void removeReference(BasicSubsystem subsystem, Resource resource) {
 		Activator.getInstance().getSubsystems().removeReference(subsystem, resource);
 	}
-	
+
 	protected final BasicSubsystem provisionTo;
 	protected final Resource resource;
 	protected final BasicSubsystem subsystem;
-	
+
 	public ResourceUninstaller(Resource resource, BasicSubsystem subsystem) {
 		if (resource == null)
 			throw new NullPointerException("Missing required parameter: resource");
@@ -61,9 +69,9 @@ public abstract class ResourceUninstalle
 		else
 			provisionTo = subsystem;
 	}
-	
+
 	public abstract void uninstall();
-	
+
 	protected boolean isExplicit() {
 		// The operation is explicit if it was requested by a user, in which
 		// case the resource and subsystem are the same.
@@ -80,14 +88,14 @@ public abstract class ResourceUninstalle
 		}
 		return false;
 	}
-	
+
 	protected boolean isTransitive() {
 		ProvisionResourceHeader header = subsystem.getDeploymentManifest().getProvisionResourceHeader();
 		if (header == null)
 			return false;
 		return header.contains(resource);
 	}
-	
+
 	protected boolean isResourceUninstallable() {
 		int referenceCount = Activator.getInstance().getSubsystems().getSubsystemsReferencing(resource).size();
 		if (referenceCount == 0)
@@ -98,11 +106,11 @@ public abstract class ResourceUninstalle
 		}
 		return false;
 	}
-	
+
 	protected void removeConstituent() {
 		removeConstituent(subsystem, resource);
 	}
-	
+
 	protected void removeReference() {
 		removeReference(subsystem, resource);
 	}

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StartAction.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StartAction.java?rev=1642910&r1=1642909&r2=1642910&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StartAction.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StartAction.java Tue Dec  2 15:38:38 2014
@@ -22,6 +22,7 @@ import java.util.EnumSet;
 import java.util.List;
 import java.util.Map.Entry;
 
+import org.apache.aries.subsystem.ContentHandler;
 import org.apache.aries.subsystem.core.archive.ExportPackageCapability;
 import org.apache.aries.subsystem.core.archive.ExportPackageHeader;
 import org.apache.aries.subsystem.core.archive.ProvideCapabilityCapability;
@@ -35,6 +36,7 @@ import org.eclipse.equinox.region.Region
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleException;
 import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
 import org.osgi.framework.namespace.IdentityNamespace;
 import org.osgi.framework.startlevel.BundleStartLevel;
 import org.osgi.framework.startlevel.FrameworkStartLevel;
@@ -54,20 +56,20 @@ import org.slf4j.LoggerFactory;
 
 public class StartAction extends AbstractAction {
 	private static final Logger logger = LoggerFactory.getLogger(StartAction.class);
-	
+
 	private final Coordination coordination;
 	private final BasicSubsystem instigator;
-	
+
 	public StartAction(BasicSubsystem instigator, BasicSubsystem requestor, BasicSubsystem target) {
 		this(instigator, requestor, target, null);
 	}
-	
+
 	public StartAction(BasicSubsystem instigator, BasicSubsystem requestor, BasicSubsystem target, Coordination coordination) {
 		super(requestor, target, false);
 		this.instigator = instigator;
 		this.coordination = coordination;
 	}
-	
+
 	@Override
 	public Object run() {
 		State state = target.getState();
@@ -119,7 +121,7 @@ public class StartAction extends Abstrac
 			// region and transition to INSTALLED.
 		} finally {
 			try {
-				// Don't end the coordination if the subsystem being started 
+				// Don't end the coordination if the subsystem being started
 				// (i.e. the target) did not begin it.
 				if (coordination.getName().equals(Utils.computeCoordinationName(target)))
 					coordination.end();
@@ -133,7 +135,7 @@ public class StartAction extends Abstrac
 		}
 		return null;
 	}
-	
+
 	private static Collection<Bundle> getBundles(BasicSubsystem subsystem) {
 		Collection<Resource> constituents = Activator.getInstance().getSubsystems().getConstituents(subsystem);
 		ArrayList<Bundle> result = new ArrayList<Bundle>(constituents.size());
@@ -144,7 +146,7 @@ public class StartAction extends Abstrac
 		result.trimToSize();
 		return result;
 	}
-	
+
 	private static void resolve(BasicSubsystem subsystem) {
 		// Don't propagate a RESOLVING event if this is a persisted subsystem
 		// that is already RESOLVED.
@@ -158,7 +160,7 @@ public class StartAction extends Abstrac
 			if (!subsystem.isRoot()) {
 				for (Subsystem child : Activator.getInstance().getSubsystems().getChildren(subsystem))
 					resolve((BasicSubsystem)child);
-				
+
 				FrameworkWiring frameworkWiring = Activator.getInstance().getBundleContext().getBundle(0)
 						.adapt(FrameworkWiring.class);
 
@@ -193,7 +195,7 @@ public class StartAction extends Abstrac
 			throw new SubsystemException(t);
 		}
 	}
-	
+
 	private static void setExportIsolationPolicy(BasicSubsystem subsystem) throws InvalidSyntaxException, IOException, BundleException, URISyntaxException, ResolutionException {
 		if (!subsystem.isComposite())
 			return;
@@ -211,7 +213,7 @@ public class StartAction extends Abstrac
 					+ ", to=" + to + ", filter=" + regionFilter);
 		from.connectRegion(to, regionFilter);
 	}
-	
+
 	private static void setExportIsolationPolicy(RegionFilterBuilder builder, ExportPackageHeader header, BasicSubsystem subsystem) throws InvalidSyntaxException {
 		if (header == null)
 			return;
@@ -226,7 +228,7 @@ public class StartAction extends Abstrac
 			builder.allow(policy, filter.toString());
 		}
 	}
-	
+
 	private static void setExportIsolationPolicy(RegionFilterBuilder builder, ProvideCapabilityHeader header, BasicSubsystem subsystem) throws InvalidSyntaxException {
 		if (header == null)
 			return;
@@ -255,7 +257,7 @@ public class StartAction extends Abstrac
 			builder.allow(policy, filter.toString());
 		}
 	}
-	
+
 	private void startBundleResource(Resource resource, Coordination coordination) throws BundleException {
 		if (target.isRoot())
 			// Starting the root subsystem should not affect bundles within the
@@ -265,11 +267,11 @@ public class StartAction extends Abstrac
 			// The region context bundle was persistently started elsewhere.
 			return;
 		final Bundle bundle = ((BundleRevision)resource).getBundle();
-		
+
 		if ((bundle.getState() & (Bundle.STARTING | Bundle.ACTIVE)) != 0)
 			return;
-		
-		if (logger.isDebugEnabled()) { 
+
+		if (logger.isDebugEnabled()) {
 			int bundleStartLevel = bundle.adapt(BundleStartLevel.class).getStartLevel();
 			Bundle systemBundle=Activator.getInstance().getBundleContext().getBundle(0);
 			int fwStartLevel = systemBundle.adapt(FrameworkStartLevel.class).getStartLevel();
@@ -278,43 +280,60 @@ public class StartAction extends Abstrac
 				+ " bundleStartLevel=" + bundleStartLevel
 				+ " frameworkStartLevel=" + fwStartLevel);
 		}
-		
+
 		bundle.start(Bundle.START_TRANSIENT | Bundle.START_ACTIVATION_POLICY);
-		
-		if (logger.isDebugEnabled()) { 
+
+		if (logger.isDebugEnabled()) {
 			logger.debug("StartAction: bundle " + bundle.getSymbolicName()
 				+ " " + bundle.getVersion().toString()
 				+ " started correctly");
 		}
-		
+
 		if (coordination == null)
 			return;
 		coordination.addParticipant(new Participant() {
 			public void ended(Coordination coordination) throws Exception {
 				// noop
 			}
-	
+
 			public void failed(Coordination coordination) throws Exception {
 				bundle.stop();
 			}
 		});
 	}
-	
+
 	private void startResource(Resource resource, Coordination coordination) throws BundleException, IOException {
 		String type = ResourceHelper.getTypeAttribute(resource);
 		if (SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION.equals(type)
 				|| SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE.equals(type)
-				|| SubsystemConstants.SUBSYSTEM_TYPE_FEATURE.equals(type))
+				|| SubsystemConstants.SUBSYSTEM_TYPE_FEATURE.equals(type)) {
 			startSubsystemResource(resource, coordination);
-		else if (IdentityNamespace.TYPE_BUNDLE.equals(type))
+	    } else if (IdentityNamespace.TYPE_BUNDLE.equals(type)) {
 			startBundleResource(resource, coordination);
-		else if (IdentityNamespace.TYPE_FRAGMENT.equals(type)) {
+	    } else if (IdentityNamespace.TYPE_FRAGMENT.equals(type)) {
 			// Fragments are not started.
+		} else {
+		    if (!startCustomHandler(resource, type, coordination))
+		        throw new SubsystemException("Unsupported resource type: " + type);
 		}
-		else
-			throw new SubsystemException("Unsupported resource type: " + type);
 	}
 
+    private boolean startCustomHandler(Resource resource, String type, Coordination coordination) {
+        ServiceReference<ContentHandler> customHandlerRef = CustomResources.getCustomContentHandler(target, type);
+        if (customHandlerRef != null) {
+            ContentHandler customHandler = target.getBundleContext().getService(customHandlerRef);
+            if (customHandler != null) {
+                try {
+                    customHandler.start(ResourceHelper.getSymbolicNameAttribute(resource), type, target, coordination);
+                    return true;
+                } finally {
+                    target.getBundleContext().ungetService(customHandlerRef);
+                }
+            }
+        }
+        return false;
+    }
+
 	private void startSubsystemResource(Resource resource, Coordination coordination) throws IOException {
 		final BasicSubsystem subsystem = (BasicSubsystem)resource;
 		// Subsystems that are content resources of another subsystem must have
@@ -328,7 +347,7 @@ public class StartAction extends Abstrac
 			public void ended(Coordination coordination) throws Exception {
 				// noop
 			}
-	
+
 			public void failed(Coordination coordination) throws Exception {
 				new StopAction(target, subsystem, !subsystem.isRoot()).run();
 			}

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StopAction.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StopAction.java?rev=1642910&r1=1642909&r2=1642910&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StopAction.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StopAction.java Tue Dec  2 15:38:38 2014
@@ -19,9 +19,11 @@ import java.util.Collections;
 import java.util.EnumSet;
 import java.util.List;
 
+import org.apache.aries.subsystem.ContentHandler;
 import org.apache.aries.subsystem.core.archive.DeploymentManifest;
 import org.apache.aries.subsystem.core.archive.SubsystemContentHeader;
 import org.osgi.framework.BundleException;
+import org.osgi.framework.ServiceReference;
 import org.osgi.framework.namespace.IdentityNamespace;
 import org.osgi.framework.wiring.BundleRevision;
 import org.osgi.resource.Resource;
@@ -33,11 +35,11 @@ import org.slf4j.LoggerFactory;
 
 public class StopAction extends AbstractAction {
 	private static final Logger logger = LoggerFactory.getLogger(StopAction.class);
-	
+
 	public StopAction(BasicSubsystem requestor, BasicSubsystem target, boolean disableRootCheck) {
 		super(requestor, target, disableRootCheck);
 	}
-	
+
 	@Override
 	public Object run() {
 		checkRoot();
@@ -63,7 +65,7 @@ public class StopAction extends Abstract
 				continue;
 			try {
 				stopResource(resource);
-			} 
+			}
 			catch (Exception e) {
 				logger.error("An error occurred while stopping resource " + resource + " of subsystem " + target, e);
 			}
@@ -88,29 +90,47 @@ public class StopAction extends Abstract
 		}
 		return null;
 	}
-	
+
 	private void stopBundleResource(Resource resource) throws BundleException {
 		if (target.isRoot())
 			return;
 		((BundleRevision)resource).getBundle().stop();
 	}
-	
+
 	private void stopResource(Resource resource) throws BundleException, IOException {
 		if (Utils.getActiveUseCount(resource) > 0)
 			return;
 		String type = ResourceHelper.getTypeAttribute(resource);
 		if (SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION.equals(type)
 				|| SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE.equals(type)
-				|| SubsystemConstants.SUBSYSTEM_TYPE_FEATURE.equals(type))
+				|| SubsystemConstants.SUBSYSTEM_TYPE_FEATURE.equals(type)) {
 			stopSubsystemResource(resource);
-		else if (IdentityNamespace.TYPE_BUNDLE.equals(type))
+		} else if (IdentityNamespace.TYPE_BUNDLE.equals(type)) {
 			stopBundleResource(resource);
-		else if (IdentityNamespace.TYPE_FRAGMENT.equals(type))
+		} else if (IdentityNamespace.TYPE_FRAGMENT.equals(type)) {
 			return;
-		else
-			throw new SubsystemException("Unsupported resource type: " + type);
+		} else {
+		    if (!stopCustomHandler(resource, type))
+		        throw new SubsystemException("Unsupported resource type: " + type);
+		}
 	}
-	
+
+    private boolean stopCustomHandler(Resource resource, String type) {
+        ServiceReference<ContentHandler> customHandlerRef = CustomResources.getCustomContentHandler(target, type);
+        if (customHandlerRef != null) {
+            ContentHandler customHandler = target.getBundleContext().getService(customHandlerRef);
+            if (customHandler != null) {
+                try {
+                    customHandler.stop(ResourceHelper.getSymbolicNameAttribute(resource), type, target);
+                    return true;
+                } finally {
+                    target.getBundleContext().ungetService(customHandlerRef);
+                }
+            }
+        }
+        return false;
+    }
+
 	private void stopSubsystemResource(Resource resource) throws IOException {
 		new StopAction(target, (BasicSubsystem)resource, !((BasicSubsystem)resource).isRoot()).run();
 	}

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResource.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResource.java?rev=1642910&r1=1642909&r2=1642910&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResource.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResource.java Tue Dec  2 15:38:38 2014
@@ -74,7 +74,7 @@ import org.osgi.service.subsystem.Subsys
 
 public class SubsystemResource implements Resource {
 	private Region region;
-	
+
 	private final List<Capability> capabilities;
 	private final DeploymentManifest deploymentManifest;
 	private final Collection<Resource> installableContent = new HashSet<Resource>();
@@ -87,11 +87,11 @@ public class SubsystemResource implement
 	private final RawSubsystemResource resource;
 	private final Collection<Resource> sharedContent = new HashSet<Resource>();
 	private final Collection<Resource> sharedDependencies = new HashSet<Resource>();
-	
+
 	public SubsystemResource(String location, IDirectory content, BasicSubsystem parent) throws URISyntaxException, IOException, ResolutionException, BundleException, InvalidSyntaxException {
-		this(new RawSubsystemResource(location, content), parent);
+		this(new RawSubsystemResource(location, content, parent), parent);
 	}
-	
+
 	public SubsystemResource(RawSubsystemResource resource, BasicSubsystem parent) throws IOException, BundleException, InvalidSyntaxException, URISyntaxException {
 		this.parent = parent;
 		this.resource = resource;
@@ -101,21 +101,21 @@ public class SubsystemResource implement
 		computeDependencies(resource.getDeploymentManifest());
 		deploymentManifest = computeDeploymentManifest();
 	}
-	
+
 	public SubsystemResource(File file) throws IOException, URISyntaxException, ResolutionException, BundleException, InvalidSyntaxException {
 		this(FileSystem.getFSRoot(file));
 	}
-	
+
 	public SubsystemResource(IDirectory directory) throws IOException, URISyntaxException, ResolutionException, BundleException, InvalidSyntaxException {
 		parent = null;
-		resource = new RawSubsystemResource(directory);
+		resource = new RawSubsystemResource(directory, parent);
 		preferredProviderRepository = null;
 		deploymentManifest = resource.getDeploymentManifest();
 		computeContentResources(deploymentManifest);
 		capabilities = computeCapabilities();
 		computeDependencies(deploymentManifest);
 	}
-	
+
 	@Override
 	public boolean equals(Object o) {
 		if (o == this)
@@ -130,7 +130,7 @@ public class SubsystemResource implement
 	public List<Capability> getCapabilities(String namespace) {
 		return Collections.unmodifiableList(capabilities);
 	}
-	
+
 	private List<Capability> computeCapabilities() throws InvalidSyntaxException {
 		List<Capability> capabilities = new ArrayList<Capability>();
 		if (isScoped())
@@ -139,18 +139,18 @@ public class SubsystemResource implement
 			computeUnscopedCapabilities(capabilities);
 		return capabilities;
 	}
-	
+
 	private void computeUnscopedCapabilities(List<Capability> capabilities) {
 		capabilities.addAll(resource.getCapabilities(null));
 		for (Resource r : getContentResources())
 			capabilities.addAll(r.getCapabilities(null));
 	}
-	
+
 	private void computeScopedCapabilities(List<Capability> capabilities) throws InvalidSyntaxException {
 		capabilities.addAll(resource.getCapabilities(null));
 		computeOsgiServiceCapabilities(capabilities);
 	}
-	
+
 	private void computeOsgiServiceCapabilities(List<Capability> capabilities) throws InvalidSyntaxException {
 		SubsystemExportServiceHeader header = getSubsystemManifest().getSubsystemExportServiceHeader();
 		if (header == null)
@@ -158,35 +158,35 @@ public class SubsystemResource implement
 		for (Resource resource : getContentResources())
 			capabilities.addAll(header.toCapabilities(resource));
 	}
-	
+
 	public DeploymentManifest getDeploymentManifest() {
 		return deploymentManifest;
 	}
-	
+
 	public long getId() {
 		return resource.getId();
 	}
-	
+
 	public Collection<Resource> getInstallableContent() {
 		return installableContent;
 	}
-	
+
 	public Collection<Resource> getInstallableDependencies() {
 		return installableDependencies;
 	}
-	
+
 	public Repository getLocalRepository() {
 		return resource.getLocalRepository();
 	}
-	
+
 	public String getLocation() {
 		return resource.getLocation().getValue();
 	}
-	
+
 	public Collection<DeployedContentHeader.Clause> getMissingResources() {
 		return missingResources;
 	}
-	
+
 	public Collection<BasicSubsystem> getParents() {
 		if (parent == null) {
 			Header<?> header = getDeploymentManifest().getHeaders().get(DeploymentManifest.ARIESSUBSYSTEM_PARENTS);
@@ -200,7 +200,7 @@ public class SubsystemResource implement
 		}
 		return Collections.singleton(parent);
 	}
-	
+
 	public synchronized Region getRegion() throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
 		if (region == null) {
 			region = createRegion(getId());
@@ -235,30 +235,30 @@ public class SubsystemResource implement
 			return result;
 		}
 	}
-	
+
 	public Collection<Resource> getResources() {
 		return resource.getResources();
 	}
-	
+
 	public Collection<Resource> getSharedContent() {
 		return sharedContent;
 	}
-	
+
 	public Collection<Resource> getSharedDependencies() {
 		return sharedDependencies;
 	}
-	
+
 	public SubsystemManifest getSubsystemManifest() {
 		return resource.getSubsystemManifest();
 	}
-	
+
 	@Override
 	public int hashCode() {
 		int result = 17;
 		result = 31 * result + getLocation().hashCode();
 		return result;
 	}
-	
+
 	private void addContentResource(Resource resource) {
 		if (resource == null)
 			return;
@@ -271,7 +271,7 @@ public class SubsystemResource implement
 		else
 			sharedContent.add(resource);
 	}
-	
+
 	private boolean addDependencies(Repository repository, Requirement requirement, List<Capability> capabilities) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
 		if (repository == null)
 			return false;
@@ -283,32 +283,32 @@ public class SubsystemResource implement
 		}
 		return !capabilities.isEmpty();
 	}
-	
+
 	private boolean addDependenciesFromContentRepository(Requirement requirement, List<Capability> capabilities) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
 		// TODO Why create this with each method call? What not cache it as an instance variable?
 		Repository repository = new ContentRepository(installableContent, sharedContent);
 		return addDependencies(repository, requirement, capabilities);
 	}
-	
+
 	private boolean addDependenciesFromLocalRepository(Requirement requirement, List<Capability> capabilities) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
 		Repository repository = resource.getLocalRepository();
 		return addDependencies(repository, requirement, capabilities);
 	}
-	
+
 	private boolean addDependenciesFromPreferredProviderRepository(Requirement requirement, List<Capability> capabilities) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
 		return addDependencies(preferredProviderRepository, requirement, capabilities);
 	}
-	
+
 	private boolean addDependenciesFromRepositoryServiceRepositories(Requirement requirement, List<Capability> capabilities) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
 		Repository repository = new RepositoryServiceRepository();
 		return addDependencies(repository, requirement, capabilities);
 	}
-	
+
 	private boolean addDependenciesFromSystemRepository(Requirement requirement, List<Capability> capabilities) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
 		Repository repository = Activator.getInstance().getSystemRepository();
 		return addDependencies(repository, requirement, capabilities);
 	}
-	
+
 	private void addDependency(Resource resource) {
 		if (resource == null)
 			return;
@@ -317,17 +317,17 @@ public class SubsystemResource implement
 		else
 			sharedDependencies.add(resource);
 	}
-	
+
 	private void addMissingResource(DeployedContentHeader.Clause resource) {
 		missingResources.add(resource);
 	}
-	
+
 	private void addValidCapabilities(Collection<Capability> from, Collection<Capability> to, Requirement requirement) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
 		for (Capability c : from)
 			if (isValid(c, requirement))
 				to.add(c);
 	}
-	
+
 	private void addSubsystemServiceImportToSharingPolicy(
 			RegionFilterBuilder builder) throws InvalidSyntaxException, BundleException, IOException, URISyntaxException {
 		builder.allow(
@@ -340,7 +340,7 @@ public class SubsystemResource implement
 						.append('=').append(getRegion().getName())
 						.append("))").toString());
 	}
-	
+
 	private void addSubsystemServiceImportToSharingPolicy(RegionFilterBuilder builder, Region to)
 			throws InvalidSyntaxException, BundleException, IOException, URISyntaxException {
 		Region root = Activator.getInstance().getSubsystems().getRootSubsystem().getRegion();
@@ -354,7 +354,7 @@ public class SubsystemResource implement
 			getRegion().connectRegion(to, regionFilter);
 		}
 	}
-	
+
 	private void computeContentResources(DeploymentManifest manifest) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
 		if (manifest == null)
 			computeContentResources(getSubsystemManifest());
@@ -371,7 +371,7 @@ public class SubsystemResource implement
 			}
 		}
 	}
-	
+
 	private void computeContentResources(SubsystemManifest manifest) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
 		SubsystemContentHeader contentHeader = manifest.getSubsystemContentHeader();
 		if (contentHeader == null)
@@ -387,7 +387,7 @@ public class SubsystemResource implement
 			addContentResource(resource);
 		}
 	}
-	
+
 	private void computeDependencies(DeploymentManifest manifest) {
 		if (manifest == null)
 			computeDependencies(getSubsystemManifest());
@@ -401,9 +401,9 @@ public class SubsystemResource implement
 					throw new SubsystemException("A required dependency could not be found. This means the resource was either missing or not recognized as a supported resource format due to, for example, an invalid bundle manifest or blueprint XML file. Turn on debug logging for more information. The resource was: " + resource);
 				addDependency(resource);
 			}
-		}	
+		}
 	}
-	
+
 	private void computeDependencies(SubsystemManifest manifest) {
 		SubsystemContentHeader contentHeader = manifest.getSubsystemContentHeader();
 		try {
@@ -425,14 +425,14 @@ public class SubsystemResource implement
 			throw new SubsystemException(e);
 		}
 	}
-	
+
 	private DeployedContentHeader computeDeployedContentHeader() {
 		Collection<Resource> content = getContentResources();
 		if (content.isEmpty())
 			return null;
 		return DeployedContentHeader.newInstance(content);
 	}
-	
+
 	private DeploymentManifest computeDeploymentManifest() throws IOException {
 		DeploymentManifest result = computeExistingDeploymentManifest();
 		if (result != null)
@@ -442,18 +442,18 @@ public class SubsystemResource implement
 				.header(computeProvisionResourceHeader()).build();
 		return result;
 	}
-	
+
 	private DeploymentManifest computeExistingDeploymentManifest() throws IOException {
 		return resource.getDeploymentManifest();
 	}
-	
+
 	private ProvisionResourceHeader computeProvisionResourceHeader() {
 		Collection<Resource> dependencies = getDepedencies();
 		if (dependencies.isEmpty())
 			return null;
 		return ProvisionResourceHeader.newInstance(dependencies);
 	}
-	
+
 	private Region createRegion(long id) throws BundleException {
 		if (!isScoped())
 			return getParents().iterator().next().getRegion();
@@ -478,11 +478,11 @@ public class SubsystemResource implement
 			return digraph.createRegion(name);
 		return region;
 	}
-	
+
 	private ResolveContext createResolveContext() {
 		return new ResolveContext() {
 			private final Map<Resource, Wiring> wirings = computeWirings();
-			
+
 			private Map<Resource, Wiring> computeWirings() {
 				Map<Resource, Wiring> wirings = new HashMap<Resource, Wiring>();
 				for (BasicSubsystem subsystem : Activator.getInstance().getSubsystems().getSubsystems())
@@ -490,7 +490,7 @@ public class SubsystemResource implement
 						addWiring(constituent, wirings);
 				return Collections.unmodifiableMap(wirings);
 			}
-			
+
 			private void addWiring(Resource resource, Map<Resource, Wiring> wirings) {
 				if (resource instanceof BundleConstituent) {
 					BundleConstituent bc = (BundleConstituent)resource;
@@ -501,13 +501,13 @@ public class SubsystemResource implement
 					wirings.put(br, br.getWiring());
 				}
 			}
-			
+
 			@Override
 			public List<Capability> findProviders(Requirement requirement) {
 				List<Capability> result = new ArrayList<Capability>();
 				try {
 					// Only check the system repository for osgi.ee and osgi.native
-					if (ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE.equals(requirement.getNamespace()) 
+					if (ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE.equals(requirement.getNamespace())
 							|| DependencyCalculator.NATIVE_NAMESPACE.equals(requirement.getNamespace())) {
 						addDependenciesFromSystemRepository(requirement, result);
 						return result;
@@ -532,12 +532,12 @@ public class SubsystemResource implement
 				}
 				return result;
 			}
-			
+
 			@Override
 			public Collection<Resource> getMandatoryResources() {
 				return SubsystemResource.this.mandatoryResources;
 			}
-			
+
 			@Override
 			public Collection<Resource> getOptionalResources() {
 				return SubsystemResource.this.optionalResources;
@@ -561,7 +561,7 @@ public class SubsystemResource implement
 			}
 		};
 	}
-	
+
 	private Resource findContent(Requirement requirement) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
 		Map<Requirement, Collection<Capability>> map;
 		// TODO System repository for scoped subsystems should be searched in
@@ -596,7 +596,7 @@ public class SubsystemResource implement
 			return capabilities.iterator().next().getResource();
 		return null;
 	}
-	
+
 	private Resource findContent(DeployedContentHeader.Clause clause) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
 		Attribute attribute = clause.getAttribute(DeployedContentHeader.Clause.ATTRIBUTE_RESOURCEID);
 		long resourceId = attribute == null ? -1 : Long.parseLong(String.valueOf(attribute.getValue()));
@@ -613,7 +613,7 @@ public class SubsystemResource implement
 		}
 		return findContent(clause.toRequirement(this));
 	}
-	
+
 	private Resource findDependency(ProvisionResourceHeader.Clause clause) {
 		Attribute attribute = clause.getAttribute(DeployedContentHeader.Clause.ATTRIBUTE_RESOURCEID);
 		long resourceId = attribute == null ? -1 : Long.parseLong(String.valueOf(attribute.getValue()));
@@ -632,54 +632,54 @@ public class SubsystemResource implement
 			return null;
 		return capabilities.get(0).getResource();
 	}
-	
+
 	private Collection<Resource> getContentResources() {
 		Collection<Resource> result = new ArrayList<Resource>(installableContent.size() + sharedContent.size());
 		result.addAll(installableContent);
 		result.addAll(sharedContent);
 		return result;
 	}
-	
+
 	private Collection<Resource> getDepedencies() {
 		Collection<Resource> result = new ArrayList<Resource>(installableDependencies.size() + sharedDependencies.size());
 		result.addAll(installableDependencies);
 		result.addAll(sharedDependencies);
 		return result;
 	}
-	
+
 	private boolean isContent(Resource resource) {
 		return getSubsystemManifest().getSubsystemContentHeader().contains(resource);
 	}
-	
+
 	private boolean isInstallable(Resource resource) {
 		return !isShared(resource);
 	}
-	
+
 	private boolean isMandatory(Resource resource) {
 		SubsystemContentHeader header = this.resource.getSubsystemManifest().getSubsystemContentHeader();
 		if (header == null)
 			return false;
 		return header.isMandatory(resource);
 	}
-	
+
 	private boolean isRoot() {
 		return BasicSubsystem.ROOT_LOCATION.equals(getLocation());
 	}
-	
+
 	private boolean isShared(Resource resource) {
 		return Utils.isSharedResource(resource);
 	}
-	
+
 	private boolean isScoped() {
 		String type = resource.getSubsystemManifest().getSubsystemTypeHeader().getType();
 		return SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION.equals(type) ||
 				SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE.equals(type);
 	}
-	
+
 	private boolean isUnscoped() {
 		return !isScoped();
 	}
-	
+
 	private boolean isValid(Capability capability, Requirement requirement) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
 		if (IdentityNamespace.IDENTITY_NAMESPACE.equals(capability.getNamespace()))
 			return true;
@@ -687,7 +687,7 @@ public class SubsystemResource implement
 		Region to = findRegionForCapabilityValidation(requirement.getResource());
 		return new SharingPolicyValidator(from, to).isValid(capability);
 	}
-	
+
 	private Region findRegionForCapabilityValidation(Resource resource) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
 		if (isInstallable(resource)) {
 			if (isContent(resource))
@@ -707,14 +707,14 @@ public class SubsystemResource implement
 				return Activator.getInstance().getSubsystems().getSubsystemsReferencing(resource).iterator().next().getRegion();
 		}
 	}
-	
+
 	private void setImportIsolationPolicy() throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
 		if (isRoot() || !isScoped())
 			return;
 		Region region = getRegion();
 		Region from = region;
 		RegionFilterBuilder builder = from.getRegionDigraph().createRegionFilterBuilder();
-		Region to = ((BasicSubsystem)getParents().iterator().next()).getRegion();
+		Region to = getParents().iterator().next().getRegion();
 		addSubsystemServiceImportToSharingPolicy(builder, to);
 		// TODO Is this check really necessary? Looks like it was done at the beginning of this method.
 		if (isScoped()) {
@@ -739,15 +739,15 @@ public class SubsystemResource implement
 		RegionFilter regionFilter = builder.build();
 		from.connectRegion(to, regionFilter);
 	}
-	
+
 	private void setImportIsolationPolicy(RegionFilterBuilder builder, ImportPackageHeader header) throws InvalidSyntaxException {
 		String policy = RegionFilter.VISIBLE_PACKAGE_NAMESPACE;
-		// work around https://www.osgi.org/bugzilla/show_bug.cgi?id=144 
-		// In the first instance, what if the various weaving services were to have a property, 
-		// osgi.woven.packages, that was a comma separated list of packages that might be woven 
-		// by that hook. 
+		// work around https://www.osgi.org/bugzilla/show_bug.cgi?id=144
+		// In the first instance, what if the various weaving services were to have a property,
+		// osgi.woven.packages, that was a comma separated list of packages that might be woven
+		// by that hook.
 		Collection<String> wovenPackages = getWovenPackages();
-		for (String pkg : wovenPackages) { 
+		for (String pkg : wovenPackages) {
 			builder.allow(policy, "(osgi.wiring.package=" + pkg + ")");
 		}
 		if (header == null)
@@ -758,23 +758,23 @@ public class SubsystemResource implement
 			builder.allow(policy, filter);
 		}
 	}
-	
-	// First pass at this: really just a sketch. 
+
+	// First pass at this: really just a sketch.
 	private Collection<String> getWovenPackages() throws InvalidSyntaxException
 	{
 		// Find all weaving services in our region
 		BundleContext bc = Activator.getInstance().getBundleContext();
 		Collection<ServiceReference<WeavingHook>> weavers = bc.getServiceReferences(WeavingHook.class, null);
 		Collection<String> wovenPackages = new ArrayList<String>();
-		for (ServiceReference<WeavingHook> sr : weavers) { 
+		for (ServiceReference<WeavingHook> sr : weavers) {
 			String someWovenPackages = (String) sr.getProperty("osgi.woven.packages");
-			if (someWovenPackages != null) { 
+			if (someWovenPackages != null) {
 				wovenPackages.addAll(ManifestHeaderProcessor.split(someWovenPackages, ","));
 			}
 		}
 		return wovenPackages;
 	}
-	
+
 	private void setImportIsolationPolicy(RegionFilterBuilder builder, RequireBundleHeader header) throws InvalidSyntaxException {
 		if (header == null)
 			return;
@@ -785,7 +785,7 @@ public class SubsystemResource implement
 			builder.allow(policy, filter);
 		}
 	}
-	
+
 	private void setImportIsolationPolicy(RegionFilterBuilder builder, RequireCapabilityHeader header) throws InvalidSyntaxException {
 		if (header == null)
 			return;
@@ -802,7 +802,7 @@ public class SubsystemResource implement
 				builder.allow(policy, filter);
 		}
 	}
-	
+
 
 	private void setImplicitAccessToNativeAndEECapabilities(RegionFilterBuilder builder) {
 		builder.allowAll(ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE);

Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceInstaller.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceInstaller.java?rev=1642910&r1=1642909&r2=1642910&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceInstaller.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceInstaller.java Tue Dec  2 15:38:38 2014
@@ -29,7 +29,7 @@ public class SubsystemResourceInstaller 
 	public SubsystemResourceInstaller(Coordination coordination, Resource resource, BasicSubsystem subsystem) {
 		super(coordination, resource, subsystem);
 	}
-	
+
 	public Resource install() throws Exception {
 		BasicSubsystem result;
 		if (resource instanceof RepositoryContent)
@@ -42,7 +42,7 @@ public class SubsystemResourceInstaller 
 			result = installSubsystemResource((SubsystemResource)resource);
 		return result;
 	}
-	
+
 	private void addChild(final BasicSubsystem child) {
 		// provisionTo will be null if the resource is an already installed
 		// dependency.
@@ -64,7 +64,7 @@ public class SubsystemResourceInstaller 
 			}
 		});
 	}
-	
+
 	private void addSubsystem(final BasicSubsystem subsystem) {
 		Activator.getInstance().getSubsystems().addSubsystem(subsystem);
 		coordination.addParticipant(new Participant() {
@@ -72,14 +72,14 @@ public class SubsystemResourceInstaller 
 			public void ended(Coordination arg0) throws Exception {
 				// Nothing
 			}
-	
+
 			@Override
 			public void failed(Coordination arg0) throws Exception {
 				Activator.getInstance().getSubsystems().removeSubsystem(subsystem);
 			}
 		});
 	}
-	
+
 	private BasicSubsystem installAriesSubsystem(BasicSubsystem subsystem) throws Exception {
 		addChild(subsystem);
 		addReference(subsystem);
@@ -124,12 +124,12 @@ public class SubsystemResourceInstaller 
 			Activator.getInstance().getSubsystemServiceRegistrar().register(subsystem, this.subsystem);
 		return subsystem;
 	}
-	
+
 	private BasicSubsystem installRawSubsystemResource(RawSubsystemResource resource) throws Exception {
 		SubsystemResource subsystemResource = new SubsystemResource(resource, provisionTo);
 		return installSubsystemResource(subsystemResource);
 	}
-	
+
 	private void installRegionContextBundle(final BasicSubsystem subsystem) throws Exception {
 		if (!subsystem.isScoped())
 			return;
@@ -146,12 +146,12 @@ public class SubsystemResourceInstaller 
 			}
 		});
 	}
-	
+
 	private BasicSubsystem installRepositoryContent(RepositoryContent resource) throws Exception {
-		RawSubsystemResource rawSubsystemResource = new RawSubsystemResource(getLocation(), FileSystem.getFSRoot(resource.getContent()));
+		RawSubsystemResource rawSubsystemResource = new RawSubsystemResource(getLocation(), FileSystem.getFSRoot(resource.getContent()), subsystem);
 		return installRawSubsystemResource(rawSubsystemResource);
 	}
-	
+
 	private BasicSubsystem installSubsystemResource(SubsystemResource resource) throws Exception {
 		BasicSubsystem subsystem = new BasicSubsystem(resource);
 		installAriesSubsystem(subsystem);

Modified: aries/trunk/subsystem/subsystem-itests/pom.xml
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/pom.xml?rev=1642910&r1=1642909&r2=1642910&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/pom.xml (original)
+++ aries/trunk/subsystem/subsystem-itests/pom.xml Tue Dec  2 15:38:38 2014
@@ -30,7 +30,7 @@
 
     <groupId>org.apache.aries.subsystem</groupId>
     <artifactId>org.apache.aries.subsystem.itests</artifactId>
-    <version>1.0.0-SNAPSHOT</version>
+    <version>1.1.0-SNAPSHOT</version>
     <name>Apache Aries Subsystem iTests</name>
     <description>
         Integration tests using the subsystem api, core for the implementation
@@ -129,7 +129,7 @@
             <groupId>org.apache.aries.subsystem</groupId>
             <artifactId>org.apache.aries.subsystem.api</artifactId>
             <scope>test</scope>
-            <version>1.0.1-SNAPSHOT</version>
+            <version>1.1.0-SNAPSHOT</version>
             <exclusions>
                 <exclusion>
                     <groupId>org.osgi</groupId>
@@ -141,7 +141,7 @@
             <groupId>org.apache.aries.subsystem</groupId>
             <artifactId>org.apache.aries.subsystem.core</artifactId>
             <scope>test</scope>
-            <version>1.1.1-SNAPSHOT</version>
+            <version>1.2.0-SNAPSHOT</version>
             <exclusions>
                 <exclusion>
                     <groupId>org.osgi</groupId>
@@ -181,7 +181,7 @@
             <groupId>org.apache.felix</groupId>
             <artifactId>org.apache.felix.configadmin</artifactId>
             <scope>test</scope>
-            <version>1.2.8</version>
+            <version>1.8.0</version>
             <exclusions>
                 <exclusion>
                     <groupId>org.osgi</groupId>
@@ -489,6 +489,85 @@
                     </execution>
 
                     <execution>
+                        <id>cm-content-bundleZ</id>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                        <configuration>
+                            <archive>
+                                <manifestFile>src/test/bundles/cmContentBundleZ/META-INF/MANIFEST.MF</manifestFile>
+                            </archive>
+                            <classesDirectory>${project.build.directory}/test-classes</classesDirectory>
+                            <includes>
+                                <include>org/apache/aries/subsystem/itests/cmcontent/impl/**</include>
+                            </includes>
+                            <outputDirectory>${project.build.directory}/test-classes/cmContent</outputDirectory>
+                            <finalName>cmContentBundleZ</finalName>
+                        </configuration>
+                        <phase>process-test-classes</phase>
+                    </execution>
+
+                    <execution>
+                        <id>custom-content-bundleA</id>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                        <configuration>
+                            <archive>
+                                <manifestFile>src/test/bundles/customContentBundleA/META-INF/MANIFEST.MF</manifestFile>
+                            </archive>
+                            <outputDirectory>${project.build.directory}/test-classes/customContent</outputDirectory>
+                            <finalName>customContentBundleA</finalName>
+                        </configuration>
+                        <phase>process-test-classes</phase>
+                    </execution>
+
+                    <execution>
+                        <id>custom-content-bundleB</id>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                        <configuration>
+                            <archive>
+                                <manifestFile>src/test/bundles/customContentBundleB/META-INF/MANIFEST.MF</manifestFile>
+                            </archive>
+                            <outputDirectory>${project.build.directory}/test-classes/customContent1</outputDirectory>
+                            <finalName>customContentBundleB</finalName>
+                        </configuration>
+                        <phase>process-test-classes</phase>
+                    </execution>
+
+                    <execution>
+                        <id>custom-content-bundleC</id>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                        <configuration>
+                            <archive>
+                                <manifestFile>src/test/bundles/customContentBundleC/META-INF/MANIFEST.MF</manifestFile>
+                            </archive>
+                            <outputDirectory>${project.build.directory}/test-classes/customContent2</outputDirectory>
+                            <finalName>customContentBundleC</finalName>
+                        </configuration>
+                        <phase>process-test-classes</phase>
+                    </execution>
+
+                    <execution>
+                        <id>custom-content-bundleD</id>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                        <configuration>
+                            <archive>
+                                <manifestFile>src/test/bundles/customContentBundleD/META-INF/MANIFEST.MF</manifestFile>
+                            </archive>
+                            <outputDirectory>${project.build.directory}/test-classes/customContent3</outputDirectory>
+                            <finalName>customContentBundleD</finalName>
+                        </configuration>
+                        <phase>process-test-classes</phase>
+                    </execution>
+
+                    <execution>
                         <id>dynamic-import-impl</id>
                         <goals>
                             <goal>jar</goal>
@@ -581,6 +660,19 @@
                     </execution>
 
                     <execution>
+                        <id>add-source-cmContentBundleZ</id>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>add-test-source</goal>
+                        </goals>
+                        <configuration>
+                            <sources>
+                                <source>src/test/bundles/cmContentBundleZ</source>
+                            </sources>
+                        </configuration>
+                    </execution>
+
+                    <execution>
                         <id>add-source-dynamicImport</id>
                         <phase>generate-sources</phase>
                         <goals>

Added: aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/META-INF/MANIFEST.MF
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/META-INF/MANIFEST.MF?rev=1642910&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/META-INF/MANIFEST.MF (added)
+++ aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/META-INF/MANIFEST.MF Tue Dec  2 15:38:38 2014
@@ -0,0 +1,8 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: CM Content Test Bundle
+Bundle-SymbolicName: org.apache.aries.subsystem.itests.cmcontent.impl
+Bundle-Version: 1.0.0
+Import-Package: org.osgi.framework, org.osgi.service.cm
+Bundle-Activator: org.apache.aries.subsystem.itests.cmcontent.impl.Activator
+

Added: aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/org/apache/aries/subsystem/itests/cmcontent/impl/Activator.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/org/apache/aries/subsystem/itests/cmcontent/impl/Activator.java?rev=1642910&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/org/apache/aries/subsystem/itests/cmcontent/impl/Activator.java (added)
+++ aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/org/apache/aries/subsystem/itests/cmcontent/impl/Activator.java Tue Dec  2 15:38:38 2014
@@ -0,0 +1,26 @@
+package org.apache.aries.subsystem.itests.cmcontent.impl;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.service.cm.ManagedService;
+
+public class Activator implements BundleActivator {
+    @Override
+    public void start(BundleContext context) throws Exception {
+        Dictionary<String, Object> blahProps = new Hashtable<String, Object>();
+        blahProps.put(Constants.SERVICE_PID, "com.blah.Blah");
+        context.registerService(ManagedService.class, new BlahManagedService(context), blahProps);
+
+        Dictionary<String, Object> barProps = new Hashtable<String, Object>();
+        barProps.put(Constants.SERVICE_PID, "org.foo.Bar");
+        context.registerService(ManagedService.class, new BarManagedService(context), barProps);
+    }
+
+    @Override
+    public void stop(BundleContext context) throws Exception {
+    }
+}

Added: aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/org/apache/aries/subsystem/itests/cmcontent/impl/BarManagedService.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/org/apache/aries/subsystem/itests/cmcontent/impl/BarManagedService.java?rev=1642910&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/org/apache/aries/subsystem/itests/cmcontent/impl/BarManagedService.java (added)
+++ aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/org/apache/aries/subsystem/itests/cmcontent/impl/BarManagedService.java Tue Dec  2 15:38:38 2014
@@ -0,0 +1,26 @@
+package org.apache.aries.subsystem.itests.cmcontent.impl;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedService;
+
+public class BarManagedService implements ManagedService {
+    private final BundleContext bundleContext;
+
+    public BarManagedService(BundleContext context) {
+        bundleContext = context;
+    }
+
+    @Override
+    public void updated(Dictionary<String, ?> p) throws ConfigurationException {
+        if ("test".equals(p.get("configVal"))) {
+            Dictionary<String, Object> props = new Hashtable<String, Object>();
+            props.put("test.pid", p.get(Constants.SERVICE_PID));
+            bundleContext.registerService(String.class, "Bar!", props);
+        }
+    }
+}

Added: aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/org/apache/aries/subsystem/itests/cmcontent/impl/BlahManagedService.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/org/apache/aries/subsystem/itests/cmcontent/impl/BlahManagedService.java?rev=1642910&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/org/apache/aries/subsystem/itests/cmcontent/impl/BlahManagedService.java (added)
+++ aries/trunk/subsystem/subsystem-itests/src/test/bundles/cmContentBundleZ/org/apache/aries/subsystem/itests/cmcontent/impl/BlahManagedService.java Tue Dec  2 15:38:38 2014
@@ -0,0 +1,27 @@
+package org.apache.aries.subsystem.itests.cmcontent.impl;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedService;
+
+public class BlahManagedService implements ManagedService {
+    private final BundleContext bundleContext;
+
+    public BlahManagedService(BundleContext context) {
+        bundleContext = context;
+    }
+
+    @Override
+    public void updated(Dictionary<String, ?> p) throws ConfigurationException {
+        if ("test2".equals(p.get("configVal")) &&
+                "test123".equals(p.get("configVal2"))) {
+            Dictionary<String, Object> props = new Hashtable<String, Object>();
+            props.put("test.pid", p.get(Constants.SERVICE_PID));
+            bundleContext.registerService(String.class, "Blah!", props);
+        }
+    }
+}

Added: aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleA/META-INF/MANIFEST.MF
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleA/META-INF/MANIFEST.MF?rev=1642910&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleA/META-INF/MANIFEST.MF (added)
+++ aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleA/META-INF/MANIFEST.MF Tue Dec  2 15:38:38 2014
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: org.apache.aries.subsystem.itests.customcontent.bundleA
+Bundle-Version: 1.0.0
+

Added: aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleB/META-INF/MANIFEST.MF
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleB/META-INF/MANIFEST.MF?rev=1642910&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleB/META-INF/MANIFEST.MF (added)
+++ aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleB/META-INF/MANIFEST.MF Tue Dec  2 15:38:38 2014
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: org.apache.aries.subsystem.itests.customcontent.bundleB
+Bundle-Version: 1.0.0
+

Added: aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleC/META-INF/MANIFEST.MF
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleC/META-INF/MANIFEST.MF?rev=1642910&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleC/META-INF/MANIFEST.MF (added)
+++ aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleC/META-INF/MANIFEST.MF Tue Dec  2 15:38:38 2014
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: org.apache.aries.subsystem.itests.customcontent.bundleC
+Bundle-Version: 1.0.0
+

Added: aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleD/META-INF/MANIFEST.MF
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleD/META-INF/MANIFEST.MF?rev=1642910&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleD/META-INF/MANIFEST.MF (added)
+++ aries/trunk/subsystem/subsystem-itests/src/test/bundles/customContentBundleD/META-INF/MANIFEST.MF Tue Dec  2 15:38:38 2014
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: org.apache.aries.subsystem.itests.customcontent.bundleD
+Bundle-Version: 1.0.0
+

Added: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/ConfigAdminPropsFileContentHandlerTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/ConfigAdminPropsFileContentHandlerTest.java?rev=1642910&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/ConfigAdminPropsFileContentHandlerTest.java (added)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/ConfigAdminPropsFileContentHandlerTest.java Tue Dec  2 15:38:38 2014
@@ -0,0 +1,79 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.aries.subsystem.itests;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.osgi.framework.Filter;
+import org.osgi.service.subsystem.Subsystem;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class ConfigAdminPropsFileContentHandlerTest extends SubsystemTest {
+    public ConfigAdminPropsFileContentHandlerTest() {
+        installConfigAdmin = true;
+    }
+
+    @Override
+    protected void createApplications() throws Exception {
+        createApplication("cmContent", "org.foo.Bar.cfg", "com.blah.Blah.cfg",
+                "cmContentBundleZ.jar");
+    }
+
+    @Test
+    public void testConfigurationContentHandler() throws Exception {
+        // This test works as follows: it first installs a subsystem (cmContent.esa)
+        // that contains two configuration files (org.foo.Bar.cfg and com.blah.Blah.cfg)
+        // These configuration files are marked as 'osgi.config' content type.
+        // The ConfigAdminContentHandler handles the installation of this content
+        // and registers them as configuration with the Config Admin Service.
+        // The .esa file also contains an ordinary bundle that registers two
+        // Config Admin ManagedServices. Each registerd under one of the PIDs.
+        // Once they receive the expected configuration they each register a String
+        // service to mark that they have.
+        // After starting the subsystem this test waits for these 'String' services
+        // to appear so that it knows that the whole process worked.
+
+        Subsystem subsystem = installSubsystemFromFile("cmContent.esa");
+        subsystem.start();
+
+        // Now check that both Managed Services (Config Admin services) have been configured
+        // If they are configured correctly they will register a marker String service to
+        // indicate this.
+
+        Filter f = bundleContext.createFilter(
+                "(&(objectClass=java.lang.String)(test.pid=org.foo.Bar))");
+        ServiceTracker<String, String> barTracker =
+                new ServiceTracker<String, String>(bundleContext, f, null);
+        try {
+            barTracker.open();
+            String blahSvc = barTracker.waitForService(2000);
+            assertEquals("Bar!", blahSvc);
+        } finally {
+            barTracker.close();
+        }
+
+        Filter f2 = bundleContext.createFilter(
+                "(&(objectClass=java.lang.String)(test.pid=com.blah.Blah))");
+        ServiceTracker<String, String> blahTracker =
+                new ServiceTracker<String, String>(bundleContext, f2, null);
+        try {
+            blahTracker.open();
+            String blahSvc = blahTracker.waitForService(2000);
+            assertEquals("Blah!", blahSvc);
+        } finally {
+            blahTracker.close();
+        }
+    }
+}

Added: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/CustomContentHandlerTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/CustomContentHandlerTest.java?rev=1642910&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/CustomContentHandlerTest.java (added)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/CustomContentHandlerTest.java Tue Dec  2 15:38:38 2014
@@ -0,0 +1,347 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.aries.subsystem.itests;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Scanner;
+
+import org.apache.aries.subsystem.ContentHandler;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Resource;
+import org.osgi.service.coordinator.Coordination;
+import org.osgi.service.subsystem.Subsystem;
+
+public class CustomContentHandlerTest extends SubsystemTest {
+
+    @Override
+    protected void createApplications() throws Exception {
+        createApplication("customContent", "custom1.sausages", "customContentBundleA.jar");
+        createApplication("customContent1", "custom2.sausages", "customContentBundleB.jar");
+        createApplication("customContent2", "custom3.sausages", "customContentBundleC.jar");
+        createApplication("customContent3", "custom4.sausages", "customContentBundleD.jar");
+    }
+
+    @Test
+    public void testCustomContentHandler() throws Exception {
+        for (Bundle b : bundleContext.getBundles()) {
+            if ("org.apache.aries.subsystem.itests.customcontent.bundleA".equals(b.getSymbolicName())) {
+                fail("Precondition");
+            }
+        }
+
+        SausagesContentHandler handler = new SausagesContentHandler();
+        Dictionary<String, Object> props = new Hashtable<String, Object>();
+        props.put(ContentHandler.CONTENT_TYPE_PROPERTY, "foo.sausages");
+        ServiceRegistration<ContentHandler> reg = bundleContext.registerService(ContentHandler.class, handler, props);
+
+        try {
+            assertEquals("Precondition", 0, handler.calls.size());
+            Subsystem subsystem = installSubsystemFromFile("customContent.esa");
+            try {
+                assertEquals(Arrays.asList("install:customContent1 sausages = 1"), handler.calls);
+
+                Collection<Resource> constituents = subsystem.getConstituents();
+                assertEquals("The custom content should not show up as a subsystem constituent",
+                        1, constituents.size());
+
+                boolean foundBundle = false;
+                for (Bundle b : bundleContext.getBundles()) {
+                    if ("org.apache.aries.subsystem.itests.customcontent.bundleA".equals(b.getSymbolicName())) {
+                        foundBundle = true;
+                    }
+                }
+                assertTrue(foundBundle);
+
+                boolean foundBundleInConstituents = false;
+                for (Resource c : constituents) {
+                    for(Capability idCap : c.getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE)) {
+                        Object name = idCap.getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE);
+                        if ("org.apache.aries.subsystem.itests.customcontent.bundleA".equals(name))
+                            foundBundleInConstituents = true;
+                    }
+                }
+                assertTrue(foundBundleInConstituents);
+
+                handler.calls.clear();
+                assertEquals(Subsystem.State.INSTALLED, subsystem.getState());
+
+                subsystem.start();
+                assertEquals(Arrays.asList("start:customContent1"), handler.calls);
+
+                handler.calls.clear();
+                assertEquals(Subsystem.State.ACTIVE, subsystem.getState());
+
+                subsystem.stop();
+                assertEquals(Arrays.asList("stop:customContent1"), handler.calls);
+
+                assertEquals(Subsystem.State.RESOLVED, subsystem.getState());
+            } finally {
+                handler.calls.clear();
+                subsystem.uninstall();
+                assertEquals(Arrays.asList("uninstall:customContent1"), handler.calls);
+                assertEquals(Subsystem.State.UNINSTALLED, subsystem.getState());
+            }
+        } finally {
+            reg.unregister();
+        }
+    }
+
+    @Test
+    public void testCustomContentInstallationException() throws Exception {
+        for (Bundle b : bundleContext.getBundles()) {
+            if ("org.apache.aries.subsystem.itests.customcontent.bundleB".equals(b.getSymbolicName())) {
+                fail("Precondition");
+            }
+        }
+
+        SausagesContentHandler handler = new SausagesContentHandler(true, "install");
+        Dictionary<String, Object> props = new Hashtable<String, Object>();
+        props.put(ContentHandler.CONTENT_TYPE_PROPERTY, "foo.sausages");
+        ServiceRegistration<ContentHandler> reg = bundleContext.registerService(ContentHandler.class, handler, props);
+
+        assertEquals("Precondition", 0, handler.calls.size());
+
+        try {
+            installSubsystemFromFile("customContent1.esa");
+        } catch (Exception ex) {
+            // ignore
+        }
+        try {
+            for (Bundle b : bundleContext.getBundles()) {
+                if ("org.apache.aries.subsystem.itests.customcontent.bundleB".equals(b.getSymbolicName())) {
+                    fail("Should not have installed the bundle");
+                }
+            }
+        } finally {
+            reg.unregister();
+        }
+    }
+
+    @Test @Ignore("This test exposes a problem that needs to be fixed, namely that the previous test leaves stuff behind and that "
+            + "customContent1.esa cannot be installed again. Currently ignored until someone finds the time to fix it.")
+    public void testCustomContentInstallationSecondTime() throws Exception {
+        for (Bundle b : bundleContext.getBundles()) {
+            if ("org.apache.aries.subsystem.itests.customcontent.bundleB".equals(b.getSymbolicName())) {
+                fail("Precondition");
+            }
+        }
+
+        SausagesContentHandler handler = new SausagesContentHandler();
+        Dictionary<String, Object> props = new Hashtable<String, Object>();
+        props.put(ContentHandler.CONTENT_TYPE_PROPERTY, "foo.sausages");
+        ServiceRegistration<ContentHandler> reg = bundleContext.registerService(ContentHandler.class, handler, props);
+
+        try {
+            Subsystem subsystem = installSubsystemFromFile("customContent1.esa");
+            subsystem.uninstall();
+        } finally {
+            reg.unregister();
+        }
+    }
+
+    @Test
+    public void testCustomContentInstallationCoordinationFails() throws Exception {
+        for (Bundle b : bundleContext.getBundles()) {
+            if ("org.apache.aries.subsystem.itests.customcontent.bundleC".equals(b.getSymbolicName())) {
+                fail("Precondition");
+            }
+        }
+
+        SausagesContentHandler handler = new SausagesContentHandler(false, "install");
+        Dictionary<String, Object> props = new Hashtable<String, Object>();
+        props.put(ContentHandler.CONTENT_TYPE_PROPERTY, "foo.sausages");
+        ServiceRegistration<ContentHandler> reg = bundleContext.registerService(ContentHandler.class, handler, props);
+
+        assertEquals("Precondition", 0, handler.calls.size());
+
+        try {
+            installSubsystemFromFile("customContent2.esa");
+        } catch (Exception ex) {
+            // ignore
+        }
+        try {
+            for (Bundle b : bundleContext.getBundles()) {
+                if ("org.apache.aries.subsystem.itests.customcontent.bundleC".equals(b.getSymbolicName())) {
+                    fail("Should not have installed the bundle");
+                }
+            }
+        } finally {
+            reg.unregister();
+        }
+    }
+
+
+
+    @Test @Ignore("This test currently doesn't pass, the bundle moves to the active state, while it shouldn't")
+    public void testCustomContentStartException() throws Exception {
+        for (Bundle b : bundleContext.getBundles()) {
+            if ("org.apache.aries.subsystem.itests.customcontent.bundleC".equals(b.getSymbolicName())) {
+                fail("Precondition");
+            }
+        }
+
+        SausagesContentHandler handler = new SausagesContentHandler(true, "start");
+        Dictionary<String, Object> props = new Hashtable<String, Object>();
+        props.put(ContentHandler.CONTENT_TYPE_PROPERTY, "foo.sausages");
+        ServiceRegistration<ContentHandler> reg = bundleContext.registerService(ContentHandler.class, handler, props);
+
+        assertEquals("Precondition", 0, handler.calls.size());
+        Subsystem subsystem = installSubsystemFromFile("customContent2.esa");
+
+        try {
+            assertEquals(Arrays.asList("install:customContent3 sausages = 3"), handler.calls);
+
+            try {
+                Bundle theBundle = null;
+                for (Bundle b : bundleContext.getBundles()) {
+                    if ("org.apache.aries.subsystem.itests.customcontent.bundleC".equals(b.getSymbolicName())) {
+                        assertEquals(Bundle.INSTALLED, b.getState());
+                        theBundle = b;
+                    }
+                }
+                assertNotNull(theBundle);
+
+                try {
+                    subsystem.start();
+                } catch (Exception ex) {
+                    // good
+                }
+                assertEquals("There was an exception during start, so the bundle should not be started",
+                        Bundle.INSTALLED, theBundle.getState());
+            } finally {
+                subsystem.uninstall();
+            }
+        } finally {
+            reg.unregister();
+        }
+    }
+
+    @Test @Ignore("This test currently doesn't pass, the bundle moves to the active state, while it shouldn't")
+    public void testCustomContentStartFailCoordination() throws Exception {
+        for (Bundle b : bundleContext.getBundles()) {
+            if ("org.apache.aries.subsystem.itests.customcontent.bundleD".equals(b.getSymbolicName())) {
+                fail("Precondition");
+            }
+        }
+
+        SausagesContentHandler handler = new SausagesContentHandler(false, "start");
+        Dictionary<String, Object> props = new Hashtable<String, Object>();
+        props.put(ContentHandler.CONTENT_TYPE_PROPERTY, "foo.sausages");
+        ServiceRegistration<ContentHandler> reg = bundleContext.registerService(ContentHandler.class, handler, props);
+
+        assertEquals("Precondition", 0, handler.calls.size());
+        Subsystem subsystem = installSubsystemFromFile("customContent3.esa");
+
+        try {
+            assertEquals(Arrays.asList("install:customContent4 sausages = 4"), handler.calls);
+
+            try {
+                Bundle theBundle = null;
+                for (Bundle b : bundleContext.getBundles()) {
+                    if ("org.apache.aries.subsystem.itests.customcontent.bundleD".equals(b.getSymbolicName())) {
+                        assertEquals(Bundle.INSTALLED, b.getState());
+                        theBundle = b;
+                    }
+                }
+                assertNotNull(theBundle);
+
+                try {
+                    subsystem.start();
+                } catch (Exception ex) {
+                    // good
+                }
+                assertEquals("The coordination failued during start, so the bundle should not be started",
+                        Bundle.INSTALLED, theBundle.getState());
+            } finally {
+                subsystem.uninstall();
+            }
+        } finally {
+            reg.unregister();
+        }
+    }
+
+    private static String convertStreamToString(InputStream is) {
+        Scanner s = new Scanner(is).useDelimiter("\\A");
+        return s.hasNext() ? s.next() : "";
+    }
+
+    static class SausagesContentHandler implements ContentHandler {
+        List<String> calls = new ArrayList<String>();
+        private final boolean exception;
+        private final String state;
+
+        public SausagesContentHandler() {
+            this(false, null);
+        }
+
+        public SausagesContentHandler(boolean exception, String state) {
+            this.exception = exception;
+            this.state = state;
+        }
+
+        @Override
+        public void install(InputStream is, String symbolicName, String type, Subsystem subsystem,
+                Coordination coordination) {
+            if ("install".equals(state)) {
+                if (exception) {
+                    throw new RuntimeException(state);
+                } else {
+                    coordination.fail(new RuntimeException(state));
+                }
+            }
+
+            String content = convertStreamToString(is);
+            calls.add(("install:" + symbolicName + " " + content).trim());
+        }
+
+        @Override
+        public void start(String symbolicName, String type, Subsystem subsystem, Coordination coordination) {
+            if ("start".equals(state)) {
+                if (exception) {
+                    throw new RuntimeException(state);
+                } else {
+                    coordination.fail(new RuntimeException(state));
+                }
+            }
+
+            calls.add("start:" + symbolicName);
+        }
+
+        @Override
+        public void stop(String symbolicName, String type, Subsystem subsystem) {
+            calls.add("stop:" + symbolicName);
+        }
+
+        @Override
+        public void uninstall(String symbolicName, String type, Subsystem subsystem) {
+            calls.add("uninstall:" + symbolicName);
+        }
+    }
+}



Mime
View raw message