You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by jw...@apache.org on 2012/05/15 20:58:42 UTC

svn commit: r1338828 - /aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/

Author: jwross
Date: Tue May 15 18:58:42 2012
New Revision: 1338828

URL: http://svn.apache.org/viewvc?rev=1338828&view=rev
Log:
ARIES-825: Initial support for security.

Added:
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/GetBundleContextAction.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/GetSubsystemHeadersAction.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/InstallAction.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SecurityManager.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StartAction.java
Modified:
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/AriesSubsystem.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResource.java

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=1338828&r1=1338827&r2=1338828&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/AriesSubsystem.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/AriesSubsystem.java Tue May 15 18:58:42 2012
@@ -20,11 +20,12 @@ import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URISyntaxException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.ArrayList;
 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;
@@ -53,7 +54,6 @@ import org.apache.aries.subsystem.core.a
 import org.apache.aries.subsystem.core.archive.SubsystemImportServiceRequirement;
 import org.apache.aries.subsystem.core.archive.SubsystemManifest;
 import org.apache.aries.subsystem.core.archive.SubsystemTypeHeader;
-import org.apache.aries.util.io.IOUtils;
 import org.eclipse.equinox.region.Region;
 import org.eclipse.equinox.region.RegionDigraph;
 import org.eclipse.equinox.region.RegionFilter;
@@ -70,7 +70,6 @@ import org.osgi.resource.Capability;
 import org.osgi.resource.Requirement;
 import org.osgi.resource.Resource;
 import org.osgi.service.coordinator.Coordination;
-import org.osgi.service.coordinator.CoordinationException;
 import org.osgi.service.coordinator.Participant;
 import org.osgi.service.repository.RepositoryContent;
 import org.osgi.service.resolver.ResolutionException;
@@ -90,8 +89,8 @@ public class AriesSubsystem implements S
 	
 	private static final Logger LOGGER = LoggerFactory.getLogger(AriesSubsystem.class);
 	
-	private static final Map<String, AriesSubsystem> locationToSubsystem = Collections.synchronizedMap(new HashMap<String, AriesSubsystem>());
-	private static final ResourceReferences resourceReferences = new ResourceReferences();
+	static final Map<String, AriesSubsystem> locationToSubsystem = Collections.synchronizedMap(new HashMap<String, AriesSubsystem>());
+	static final ResourceReferences resourceReferences = new ResourceReferences();
 	private static final Map<Resource, Set<AriesSubsystem>> resourceToSubsystems = Collections.synchronizedMap(new HashMap<Resource, Set<AriesSubsystem>>());
 	
 	static synchronized Collection<AriesSubsystem> getSubsystems(Resource resource) {
@@ -149,10 +148,10 @@ public class AriesSubsystem implements S
 	private final long id;
 	private final String location;
 	private final Region region;
-	private final SubsystemResource resource;
+	final SubsystemResource resource;
 	private final SubsystemGraph subsystemGraph;
 	
-	private boolean autostart;
+	boolean autostart;
 	private Subsystem.State state = State.INSTALLING;
 	 
 	public AriesSubsystem() throws Exception {
@@ -229,7 +228,7 @@ public class AriesSubsystem implements S
 		LOGGER.debug(LOG_EXIT, "init");
 	}
 	
-	public AriesSubsystem(SubsystemResource resource, AriesSubsystem parent) throws Exception {
+	public AriesSubsystem(SubsystemResource resource, AriesSubsystem parent) {
 		this.resource = resource;
 		subsystemGraph = parent.subsystemGraph;
 		this.location = resource.getLocation();
@@ -237,7 +236,7 @@ public class AriesSubsystem implements S
 		String directoryName = "subsystem" + id;
 		directory = new File(Activator.getInstance().getBundleContext().getDataFile(""), directoryName);
 		if (!directory.mkdir())
-			throw new IOException("Unable to make directory for " + directory.getCanonicalPath());
+			throw new SubsystemException("Unable to make directory for " + directory.getAbsolutePath());
 		try {
 			archive = new SubsystemArchive(resource, directory);
 			archive.setSubsystemManifest(resource.getSubsystemManifest());
@@ -282,14 +281,8 @@ public class AriesSubsystem implements S
 	
 	@Override
 	public BundleContext getBundleContext() {
-		if (EnumSet.of(State.INSTALL_FAILED, State.UNINSTALLED).contains(
-				getState()))
-			return null;
-		AriesSubsystem subsystem = findScopedSubsystemInRegion();
-		return region.getBundle(
-				RegionContextBundleHelper.SYMBOLICNAME_PREFIX
-						+ subsystem.getSubsystemId(),
-				RegionContextBundleHelper.VERSION).getBundleContext();
+		SecurityManager.checkContextPermission(this);
+		return AccessController.doPrivileged(new GetBundleContextAction(this));
 	}
 	
 	@Override
@@ -323,6 +316,7 @@ public class AriesSubsystem implements S
 
 	@Override
 	public String getLocation() {
+		SecurityManager.checkMetadataPermission(this);
 		return location;
 	}
 
@@ -349,13 +343,8 @@ public class AriesSubsystem implements S
 	
 	@Override
 	public Map<String, String> getSubsystemHeaders(Locale locale) {
-		Map<String, Header<?>> headers = archive.getSubsystemManifest().getHeaders();
-		Map<String, String> result = new HashMap<String, String>(headers.size());
-		for (Entry<String, Header<?>> entry: headers.entrySet()) {
-			Header<?> value = entry.getValue();
-			result.put(entry.getKey(), value.getValue());
-		}
-		return result;
+		SecurityManager.checkMetadataPermission(this);
+		return AccessController.doPrivileged(new GetSubsystemHeadersAction(this));
 	}
 
 	@Override
@@ -384,27 +373,9 @@ public class AriesSubsystem implements S
 	}
 	
 	@Override
-	public Subsystem install(String location, InputStream content) throws SubsystemException {
-		Coordination coordination = Activator.getInstance().getCoordinator().create(getSymbolicName() + '-' + getSubsystemId(), 0);
-		Subsystem result = null;
-		try {
-			result = install(location, content, coordination);
-		}
-		catch (Throwable t) {
-			coordination.fail(t);
-		}
-		finally {
-			try {
-				coordination.end();
-			}
-			catch (CoordinationException e) {
-				Throwable t = e.getCause();
-				if (t instanceof SubsystemException)
-					throw (SubsystemException)t;
-				throw new SubsystemException(t);
-			}
-		}
-		return result;
+	// TODO Remove this synchronization when the 'location lock' has been implemented.
+	public synchronized Subsystem install(String location, InputStream content) throws SubsystemException {
+		return AccessController.doPrivileged(new InstallAction(location, content, this, AccessController.getContext()));
 	}
 	
 	public boolean isApplication() {
@@ -432,48 +403,8 @@ public class AriesSubsystem implements S
 	 */
 	@Override
 	public synchronized void start() throws SubsystemException {
-		State state = getState();
-		if (state == State.UNINSTALLING || state == State.UNINSTALLED)
-			throw new SubsystemException("Cannot stop from state " + state);
-		if (state == State.INSTALLING || state == State.RESOLVING || state == State.STOPPING) {
-			waitForStateChange();
-			start();
-			return;
-		}
-		// TODO Should we wait on STARTING to see if the outcome is ACTIVE?
-		if (state == State.STARTING || state == State.ACTIVE)
-			return;
-		resolve();
-		setState(State.STARTING);
-		autostart = true;
-		// TODO Need to hold a lock here to guarantee that another start
-		// operation can't occur when the state goes to RESOLVED.
-		// Start the subsystem.
-		Coordination coordination = Activator.getInstance()
-				.getCoordinator()
-				.create(getSymbolicName() + '-' + getSubsystemId(), 0);
-		try {
-			List<Resource> resources = new ArrayList<Resource>(resourceReferences.getResources(this));
-			if (resource != null)
-				Collections.sort(resources, new StartResourceComparator(resource.getSubsystemManifest().getSubsystemContentHeader()));
-			for (Resource resource : resources)
-				startResource(resource, coordination);
-			setState(State.ACTIVE);
-		} catch (Throwable t) {
-			coordination.fail(t);
-			// TODO Need to reinstate complete isolation by disconnecting the
-			// region and transition to INSTALLED.
-		} finally {
-			try {
-				coordination.end();
-			} catch (CoordinationException e) {
-				setState(State.RESOLVED);
-				Throwable t = e.getCause();
-				if (t instanceof SubsystemException)
-					throw (SubsystemException)t;
-				throw new SubsystemException(t);
-			}
-		}
+		SecurityManager.checkExecutePermission(this);
+		AccessController.doPrivileged(new StartAction(this));
 	}
 	
 	/* INSTALLING	Noop
@@ -489,10 +420,18 @@ public class AriesSubsystem implements S
 	 */
 	@Override
 	public synchronized void stop() throws SubsystemException {
-		// The root subsystem may not be stopped.
-		checkRoot();
-		autostart = false;
-		stop0();
+		SecurityManager.checkExecutePermission(this);
+		AccessController.doPrivileged(new PrivilegedAction<Object>() {
+			@Override
+			public Object run() {
+				// The root subsystem may not be stopped.
+				checkRoot();
+				autostart = false;
+				stop0();
+				return null;
+			}
+			
+		});
 	}
 	
 	/* INSTALLING	Wait, Uninstall
@@ -508,21 +447,28 @@ public class AriesSubsystem implements S
 	 */
 	@Override
 	public synchronized void uninstall() throws SubsystemException {
-		// The root subsystem may not be uninstalled.
-		checkRoot();
-		State state = getState();
-		if (state == State.UNINSTALLING || state == State.UNINSTALLED || state == State.INSTALL_FAILED) {
-			return;
-		}
-		else if (state == State.INSTALLING || state == State.RESOLVING || state == State.STARTING || state == State.STOPPING) {
-			waitForStateChange();
-			uninstall();
-		}
-		else if (getState() == State.ACTIVE) {
-			stop();
-			uninstall();
-		}
-		uninstall(true);
+		SecurityManager.checkLifecyclePermission(this);
+		AccessController.doPrivileged(new PrivilegedAction<Object>() {
+			@Override
+			public Object run() {
+				// The root subsystem may not be uninstalled.
+				checkRoot();
+				State state = getState();
+				if (state == State.UNINSTALLING || state == State.UNINSTALLED || state == State.INSTALL_FAILED) {
+					return null;
+				}
+				else if (state == State.INSTALLING || state == State.RESOLVING || state == State.STARTING || state == State.STOPPING) {
+					waitForStateChange();
+					uninstall();
+				}
+				else if (getState() == State.ACTIVE) {
+					stop();
+					uninstall();
+				}
+				uninstall(true);
+				return null;
+			}
+		});
 	}
 	
 	synchronized void bundleInstalled(BundleRevision revision) {
@@ -535,6 +481,13 @@ public class AriesSubsystem implements S
 		removeResourceToSubsystem(revision, this);
 	}
 	
+	AriesSubsystem findScopedSubsystemInRegion() {
+		AriesSubsystem result = this;
+		while (!result.isScoped())
+			result = (AriesSubsystem)result.getParents().iterator().next();
+		return result;
+	}
+	
 	Region getRegion() {
 		return region;
 	}
@@ -633,7 +586,7 @@ public class AriesSubsystem implements S
 		notifyAll();
 	}
 	
-	protected synchronized void waitForStateChange() {
+	synchronized void waitForStateChange() {
 		try {
 			wait();
 		}
@@ -698,13 +651,6 @@ public class AriesSubsystem implements S
 		return root;
 	}
 	
-	private AriesSubsystem findScopedSubsystemInRegion() {
-		AriesSubsystem result = this;
-		while (!result.isScoped())
-			result = (AriesSubsystem)result.getParents().iterator().next();
-		return result;
-	}
-	
 	private DeploymentManifest getDeploymentManifest() throws IOException, URISyntaxException, ResolutionException {
 		if (archive.getDeploymentManifest() == null)
 			archive.setDeploymentManifest(new DeploymentManifest(
@@ -751,48 +697,6 @@ public class AriesSubsystem implements S
 		if (autostart)
 			start();
 	}
-	
-	private synchronized Subsystem install(String location, InputStream content, Coordination coordination) throws SubsystemException {
-		SubsystemResource ssr = null;
-		try {
-			TargetRegion region = new TargetRegion(this);
-			ssr = new SubsystemResource(location, content, this);
-			AriesSubsystem subsystem = locationToSubsystem.get(location);
-			if (subsystem != null) {
-				if (!region.contains(subsystem))
-					throw new SubsystemException("Location already exists but existing subsystem is not part of target region: " + location);
-				if (!(subsystem.getSymbolicName().equals(ssr.getSubsystemManifest().getSubsystemSymbolicNameHeader().getSymbolicName())
-						&& subsystem.getVersion().equals(ssr.getSubsystemManifest().getSubsystemVersionHeader().getVersion())
-						&& subsystem.getType().equals(ssr.getSubsystemManifest().getSubsystemTypeHeader().getType())))
-					throw new SubsystemException("Location already exists but symbolic name, version, and type are not the same: " + location);
-				subsystemInstalling(subsystem);
-				subsystemInstalled(subsystem);
-				return subsystem;
-			}
-			subsystem = (AriesSubsystem)region.find(
-					ssr.getSubsystemManifest().getSubsystemSymbolicNameHeader().getSymbolicName(), 
-					ssr.getSubsystemManifest().getSubsystemVersionHeader().getVersion());
-			if (subsystem != null) {
-				if (!subsystem.getType().equals(ssr.getSubsystemManifest().getSubsystemTypeHeader().getType()))
-					throw new SubsystemException("Subsystem already exists in target region but has a different type: " + location);
-				subsystemInstalling(subsystem);
-				subsystemInstalled(subsystem);
-				return subsystem;
-			}
-			subsystem = new AriesSubsystem(ssr, this);
-			installResource(subsystem, coordination, false);
-			return subsystem;
-		}
-		catch (SubsystemException e) {
-			throw e;
-		}
-		catch (Exception e) {
-			throw new SubsystemException(e);
-		}
-		finally {
-			IOUtils.close(content);
-		}
-	}
 
 	private Resource installBundleResource(Resource resource,
 			Coordination coordination, boolean transitive)
@@ -842,7 +746,7 @@ public class AriesSubsystem implements S
 		return revision;
 	}
 
-	private void installResource(Resource resource, Coordination coordination, boolean transitive) throws Exception {
+	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)
@@ -872,8 +776,8 @@ public class AriesSubsystem implements S
 		final AriesSubsystem subsystem;
 		if (resource instanceof RepositoryContent) {
 			String location = getSubsystemId() + "@" + getSymbolicName() + "@" + ResourceHelper.getSymbolicNameAttribute(resource);
-			subsystem = (AriesSubsystem)install(location, ((RepositoryContent)resource).getContent(), coordination);
-			return subsystem;
+			InputStream content = ((RepositoryContent)resource).getContent();
+			return AccessController.doPrivileged(new InstallAction(location, content, this, null, coordination, true));
 		}
 		else if (resource instanceof AriesSubsystem) {
 			subsystem = (AriesSubsystem)resource;
@@ -917,7 +821,7 @@ public class AriesSubsystem implements S
 		return isApplication() || isComposite();
 	}
 	
-	private void resolve() {
+	void resolve() {
 		if (state != State.INSTALLED)
 			return;
 		setState(State.RESOLVING);
@@ -1124,7 +1028,7 @@ public class AriesSubsystem implements S
 		});
 	}
 
-	private void startResource(Resource resource, Coordination coordination) throws BundleException, IOException {
+	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)
@@ -1177,11 +1081,11 @@ public class AriesSubsystem implements S
 		((AriesSubsystem)resource).stop();
 	}
 	
-	private synchronized void subsystemInstalled(AriesSubsystem subsystem) {
+	synchronized void subsystemInstalled(AriesSubsystem subsystem) {
 		Activator.getInstance().getSubsystemServiceRegistrar().addRegion(subsystem, region);
 	}
 	
-	private synchronized void subsystemInstalling(AriesSubsystem subsystem) {
+	synchronized void subsystemInstalling(AriesSubsystem subsystem) {
 		locationToSubsystem.put(subsystem.getLocation(), subsystem);
 		subsystemGraph.add(this, subsystem);
 		addResourceToSubsystem(subsystem, this);

Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/GetBundleContextAction.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/GetBundleContextAction.java?rev=1338828&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/GetBundleContextAction.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/GetBundleContextAction.java Tue May 15 18:58:42 2012
@@ -0,0 +1,27 @@
+package org.apache.aries.subsystem.core.internal;
+
+import java.security.PrivilegedAction;
+import java.util.EnumSet;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.service.subsystem.Subsystem.State;
+
+public class GetBundleContextAction implements PrivilegedAction<BundleContext> {
+	private final AriesSubsystem subsystem;
+	
+	public GetBundleContextAction(AriesSubsystem subsystem) {
+		this.subsystem = subsystem;
+	}
+	
+	@Override
+	public BundleContext run() {
+		if (EnumSet.of(State.INSTALL_FAILED, State.UNINSTALLED).contains(
+				subsystem.getState()))
+			return null;
+		AriesSubsystem subsystem = this.subsystem.findScopedSubsystemInRegion();
+		return subsystem.getRegion().getBundle(
+				RegionContextBundleHelper.SYMBOLICNAME_PREFIX
+						+ subsystem.getSubsystemId(),
+				RegionContextBundleHelper.VERSION).getBundleContext();
+	}
+}

Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/GetSubsystemHeadersAction.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/GetSubsystemHeadersAction.java?rev=1338828&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/GetSubsystemHeadersAction.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/GetSubsystemHeadersAction.java Tue May 15 18:58:42 2012
@@ -0,0 +1,28 @@
+package org.apache.aries.subsystem.core.internal;
+
+import java.security.PrivilegedAction;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.aries.subsystem.core.archive.Header;
+
+public class GetSubsystemHeadersAction implements PrivilegedAction<Map<String, String>> {
+	private final AriesSubsystem subsystem;
+	
+	public GetSubsystemHeadersAction(AriesSubsystem subsystem) {
+		this.subsystem = subsystem;
+	}
+	
+	@Override
+	public Map<String, String> run() {
+		Map<String, Header<?>> headers = subsystem.getArchive().getSubsystemManifest().getHeaders();
+		Map<String, String> result = new HashMap<String, String>(headers.size());
+		for (Entry<String, Header<?>> entry: headers.entrySet()) {
+			Header<?> value = entry.getValue();
+			result.put(entry.getKey(), value.getValue());
+		}
+		return result;
+	}
+
+}

Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/InstallAction.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/InstallAction.java?rev=1338828&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/InstallAction.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/InstallAction.java Tue May 15 18:58:42 2012
@@ -0,0 +1,101 @@
+package org.apache.aries.subsystem.core.internal;
+
+import java.io.InputStream;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.osgi.service.coordinator.Coordination;
+import org.osgi.service.coordinator.CoordinationException;
+import org.osgi.service.subsystem.SubsystemException;
+
+public class InstallAction implements PrivilegedAction<AriesSubsystem> {
+	private final InputStream content;
+	private final AccessControlContext context;
+	private final Coordination coordination;
+	private final boolean embedded;
+	private final String location;
+	private final AriesSubsystem parent;
+	
+	public InstallAction(String location, InputStream content, AriesSubsystem parent, AccessControlContext context) {
+		this(location, content, parent, context, null, false);
+	}
+	
+	public InstallAction(String location, InputStream content, AriesSubsystem parent, AccessControlContext context, Coordination coordination, boolean embedded) {
+		this.location = location;
+		this.content = content;
+		this.parent = parent;
+		this.context = context;
+		this.coordination = coordination;
+		this.embedded = embedded;
+	}
+	
+	@Override
+	public AriesSubsystem run() {
+		AriesSubsystem result = null;
+		Coordination coordination = this.coordination;
+		if (coordination == null)
+			coordination = Activator.getInstance().getCoordinator().create(parent.getSymbolicName() + '-' + parent.getSubsystemId(), 0);
+		try {
+			TargetRegion region = new TargetRegion(parent);
+			SubsystemResource ssr = new SubsystemResource(location, content, parent);
+			result = AriesSubsystem.locationToSubsystem.get(location);
+			if (result != null) {
+				checkLifecyclePermission(result);
+				if (!region.contains(result))
+					throw new SubsystemException("Location already exists but existing subsystem is not part of target region: " + location);
+				if (!(result.getSymbolicName().equals(ssr.getSubsystemManifest().getSubsystemSymbolicNameHeader().getSymbolicName())
+						&& result.getVersion().equals(ssr.getSubsystemManifest().getSubsystemVersionHeader().getVersion())
+						&& result.getType().equals(ssr.getSubsystemManifest().getSubsystemTypeHeader().getType())))
+					throw new SubsystemException("Location already exists but symbolic name, version, and type are not the same: " + location);
+				parent.subsystemInstalling(result);
+				parent.subsystemInstalled(result);
+				return result;
+			}
+			result = (AriesSubsystem)region.find(
+					ssr.getSubsystemManifest().getSubsystemSymbolicNameHeader().getSymbolicName(), 
+					ssr.getSubsystemManifest().getSubsystemVersionHeader().getVersion());
+			if (result != null) {
+				checkLifecyclePermission(result);
+				if (!result.getType().equals(ssr.getSubsystemManifest().getSubsystemTypeHeader().getType()))
+					throw new SubsystemException("Subsystem already exists in target region but has a different type: " + location);
+				parent.subsystemInstalling(result);
+				parent.subsystemInstalled(result);
+				return result;
+			}
+			result = new AriesSubsystem(ssr, parent);
+			checkLifecyclePermission(result);
+			parent.installResource(result, coordination, false);
+		}
+		catch (Throwable t) {
+			coordination.fail(t);
+		}
+		finally {
+			try {
+				coordination.end();
+			}
+			catch (CoordinationException e) {
+				Throwable t = e.getCause();
+				if (t instanceof SubsystemException)
+					throw (SubsystemException)t;
+				if (t instanceof SecurityException)
+					throw (SecurityException)t;
+				throw new SubsystemException(t);
+			}
+		}
+		return result;
+	}
+
+	private void checkLifecyclePermission(final AriesSubsystem subsystem) {
+		if (embedded)
+			return;
+		AccessController.doPrivileged(new PrivilegedAction<Object>() {
+			@Override
+			public Object run() {
+				SecurityManager.checkLifecyclePermission(subsystem);
+				return null;
+			}
+		},
+		context);
+	}
+}

Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SecurityManager.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SecurityManager.java?rev=1338828&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SecurityManager.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SecurityManager.java Tue May 15 18:58:42 2012
@@ -0,0 +1,29 @@
+package org.apache.aries.subsystem.core.internal;
+
+import org.osgi.service.subsystem.Subsystem;
+import org.osgi.service.subsystem.SubsystemPermission;
+
+public class SecurityManager {
+	public static void checkContextPermission(Subsystem subsystem) {
+		checkPermission(new SubsystemPermission(subsystem, SubsystemPermission.CONTEXT));
+	}
+	
+	public static void checkExecutePermission(Subsystem subsystem) {
+		checkPermission(new SubsystemPermission(subsystem, SubsystemPermission.EXECUTE));
+	}
+	
+	public static void checkLifecyclePermission(Subsystem subsystem) {
+		checkPermission(new SubsystemPermission(subsystem, SubsystemPermission.LIFECYCLE));
+	}
+	
+	public static void checkMetadataPermission(Subsystem subsystem) {
+		checkPermission(new SubsystemPermission(subsystem, SubsystemPermission.METADATA));
+	}
+	
+	public static void checkPermission(SubsystemPermission permission) {
+		java.lang.SecurityManager sm = System.getSecurityManager();
+		if (sm == null)
+			return;
+		sm.checkPermission(permission);
+	}
+}

Added: 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=1338828&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StartAction.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StartAction.java Tue May 15 18:58:42 2012
@@ -0,0 +1,67 @@
+package org.apache.aries.subsystem.core.internal;
+
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.osgi.resource.Resource;
+import org.osgi.service.coordinator.Coordination;
+import org.osgi.service.coordinator.CoordinationException;
+import org.osgi.service.subsystem.SubsystemException;
+import org.osgi.service.subsystem.Subsystem.State;
+
+public class StartAction implements PrivilegedAction<Object> {
+	private final AriesSubsystem subsystem;
+	
+	public StartAction(AriesSubsystem subsystem) {
+		this.subsystem = subsystem;
+	}
+	
+	@Override
+	public Object run() {
+		State state = subsystem.getState();
+		if (state == State.UNINSTALLING || state == State.UNINSTALLED)
+			throw new SubsystemException("Cannot stop from state " + state);
+		if (state == State.INSTALLING || state == State.RESOLVING || state == State.STOPPING) {
+			subsystem.waitForStateChange();
+			subsystem.start();
+			return null;
+		}
+		// TODO Should we wait on STARTING to see if the outcome is ACTIVE?
+		if (state == State.STARTING || state == State.ACTIVE)
+			return null;
+		subsystem.resolve();
+		subsystem.setState(State.STARTING);
+		subsystem.autostart = true;
+		// TODO Need to hold a lock here to guarantee that another start
+		// operation can't occur when the state goes to RESOLVED.
+		// Start the subsystem.
+		Coordination coordination = Activator.getInstance()
+				.getCoordinator()
+				.create(subsystem.getSymbolicName() + '-' + subsystem.getSubsystemId(), 0);
+		try {
+			List<Resource> resources = new ArrayList<Resource>(AriesSubsystem.resourceReferences.getResources(subsystem));
+			if (subsystem.resource != null)
+				Collections.sort(resources, new StartResourceComparator(subsystem.resource.getSubsystemManifest().getSubsystemContentHeader()));
+			for (Resource resource : resources)
+				subsystem.startResource(resource, coordination);
+			subsystem.setState(State.ACTIVE);
+		} catch (Throwable t) {
+			coordination.fail(t);
+			// TODO Need to reinstate complete isolation by disconnecting the
+			// region and transition to INSTALLED.
+		} finally {
+			try {
+				coordination.end();
+			} catch (CoordinationException e) {
+				subsystem.setState(State.RESOLVED);
+				Throwable t = e.getCause();
+				if (t instanceof SubsystemException)
+					throw (SubsystemException)t;
+				throw new SubsystemException(t);
+			}
+		}
+		return null;
+	}
+}

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=1338828&r1=1338827&r2=1338828&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 May 15 18:58:42 2012
@@ -40,7 +40,7 @@ public class SubsystemResource implement
 	private final Collection<Resource> sharedContent = new HashSet<Resource>();
 	private final Collection<Resource> sharedDependencies = new HashSet<Resource>();
 	
-	public SubsystemResource(String location, InputStream content, AriesSubsystem parent) throws UnsupportedOperationException, URISyntaxException, IOException, ResolutionException {
+	public SubsystemResource(String location, InputStream content, AriesSubsystem parent) throws URISyntaxException, IOException, ResolutionException {
 		this(new RawSubsystemResource(location, content), parent);
 	}