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/06/24 21:48:45 UTC
svn commit: r1353319 [2/3] - in /aries/trunk/subsystem:
subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/
subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/
subsystem-itests/src/test/java/org/apache/aries/subsyst...
Modified: 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=1353319&r1=1353318&r2=1353319&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/GetBundleContextAction.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/GetBundleContextAction.java Sun Jun 24 19:48:40 2012
@@ -18,7 +18,7 @@ public class GetBundleContextAction impl
if (EnumSet.of(State.INSTALL_FAILED, State.UNINSTALLED).contains(
subsystem.getState()))
return null;
- AriesSubsystem subsystem = this.subsystem.findScopedSubsystemInRegion();
+ AriesSubsystem subsystem = Utils.findScopedSubsystemInRegion(this.subsystem);
return subsystem.getRegion().getBundle(
RegionContextBundleHelper.SYMBOLICNAME_PREFIX
+ subsystem.getSubsystemId(),
Modified: 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=1353319&r1=1353318&r2=1353319&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/GetSubsystemHeadersAction.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/GetSubsystemHeadersAction.java Sun Jun 24 19:48:40 2012
@@ -16,7 +16,7 @@ public class GetSubsystemHeadersAction i
@Override
public Map<String, String> run() {
- Map<String, Header<?>> headers = subsystem.getArchive().getSubsystemManifest().getHeaders();
+ Map<String, Header<?>> headers = subsystem.getSubsystemManifest().getHeaders();
Map<String, String> result = new HashMap<String, String>(headers.size());
for (Entry<String, Header<?>> entry: headers.entrySet()) {
Header<?> value = entry.getValue();
Modified: 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=1353319&r1=1353318&r2=1353319&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/InstallAction.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/InstallAction.java Sun Jun 24 19:48:40 2012
@@ -1,14 +1,19 @@
package org.apache.aries.subsystem.core.internal;
+import java.io.IOException;
import java.io.InputStream;
+import java.net.URISyntaxException;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import org.apache.aries.util.io.IOUtils;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.InvalidSyntaxException;
import org.osgi.service.coordinator.Coordination;
import org.osgi.service.coordinator.CoordinationException;
import org.osgi.service.coordinator.Participant;
+import org.osgi.service.resolver.ResolutionException;
import org.osgi.service.subsystem.SubsystemException;
public class InstallAction implements PrivilegedAction<AriesSubsystem> {
@@ -28,6 +33,8 @@ public class InstallAction implements Pr
this.content = content;
this.parent = parent;
this.context = context;
+ if (coordination == null)
+ coordination = Utils.createCoordination(parent);
this.coordination = coordination;
this.embedded = embedded;
}
@@ -35,23 +42,9 @@ public class InstallAction implements Pr
@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);
- final SubsystemResource ssr = new SubsystemResource(location, content, parent);
- coordination.addParticipant(new Participant() {
- @Override
- public void ended(Coordination c) throws Exception {
- // Nothing
- }
-
- @Override
- public void failed(Coordination c) throws Exception {
- IOUtils.deleteRecursive(ssr.getDirectory());
- }
- });
+ SubsystemResource ssr = createSubsystemResource(location, content, parent);
result = Activator.getInstance().getSubsystems().getSubsystemByLocation(location);
if (result != null) {
checkLifecyclePermission(result);
@@ -61,8 +54,7 @@ public class InstallAction implements Pr
&& 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.installResource(result);
- return result;
+ return (AriesSubsystem)ResourceInstaller.newInstance(coordination, result, parent, false).install();
}
result = (AriesSubsystem)region.find(
ssr.getSubsystemManifest().getSubsystemSymbolicNameHeader().getSymbolicName(),
@@ -71,12 +63,11 @@ public class InstallAction implements Pr
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.installResource(result);
- return result;
+ return (AriesSubsystem)ResourceInstaller.newInstance(coordination, result, parent, false).install();
}
- result = new AriesSubsystem(ssr, parent);
+ result = createSubsystem(ssr);
checkLifecyclePermission(result);
- parent.installResource(result, coordination, false);
+ return (AriesSubsystem)ResourceInstaller.newInstance(coordination, result, parent, false).install();
}
catch (Throwable t) {
coordination.fail(t);
@@ -109,4 +100,37 @@ public class InstallAction implements Pr
},
context);
}
+
+ private AriesSubsystem createSubsystem(SubsystemResource resource) throws URISyntaxException, IOException, BundleException, InvalidSyntaxException {
+ final AriesSubsystem result = new AriesSubsystem(resource);
+ coordination.addParticipant(new Participant() {
+ @Override
+ public void ended(Coordination c) throws Exception {
+ // Nothing
+ }
+
+ @Override
+ public void failed(Coordination c) throws Exception {
+ IOUtils.deleteRecursive(result.getDirectory());
+ }
+ });
+ return result;
+
+ }
+
+ private SubsystemResource createSubsystemResource(String location, InputStream content, AriesSubsystem parent) throws URISyntaxException, IOException, ResolutionException {
+ final SubsystemResource result = new SubsystemResource(location, content, parent);
+// coordination.addParticipant(new Participant() {
+// @Override
+// public void ended(Coordination c) throws Exception {
+// // Nothing
+// }
+//
+// @Override
+// public void failed(Coordination c) throws Exception {
+// IOUtils.deleteRecursive(result.getDirectory());
+// }
+// });
+ return result;
+ }
}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/PreferredProviderRepository.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/PreferredProviderRepository.java?rev=1353319&r1=1353318&r2=1353319&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/PreferredProviderRepository.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/PreferredProviderRepository.java Sun Jun 24 19:48:40 2012
@@ -89,6 +89,6 @@ public class PreferredProviderRepository
}
private boolean isValid(Capability capability) {
- return resource.getParent().getConstituents().contains(capability.getResource());
+ return resource.getParents().iterator().next().getConstituents().contains(capability.getResource());
}
}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/RawSubsystemResource.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/RawSubsystemResource.java?rev=1353319&r1=1353318&r2=1353319&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/RawSubsystemResource.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/RawSubsystemResource.java Sun Jun 24 19:48:40 2012
@@ -1,7 +1,6 @@
package org.apache.aries.subsystem.core.internal;
import java.io.File;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
@@ -22,6 +21,7 @@ import org.apache.aries.subsystem.core.a
import org.apache.aries.subsystem.core.archive.SubsystemContentHeader;
import org.apache.aries.subsystem.core.archive.SubsystemManifest;
import org.apache.aries.subsystem.core.archive.SubsystemSymbolicNameHeader;
+import org.apache.aries.subsystem.core.archive.SubsystemTypeHeader;
import org.apache.aries.subsystem.core.archive.SubsystemVersionHeader;
import org.apache.aries.util.filesystem.FileSystem;
import org.apache.aries.util.filesystem.IDirectory;
@@ -37,7 +37,7 @@ import org.osgi.resource.Resource;
import org.osgi.service.repository.Repository;
import org.osgi.service.resolver.ResolutionException;
import org.osgi.service.subsystem.SubsystemConstants;
-import org.osgi.service.subsystem.SubsystemException;
+import org.osgi.service.subsystem.Subsystem.State;
public class RawSubsystemResource implements Resource {
private static final Pattern PATTERN = Pattern.compile("([^@]+)(?:@(.+))?.esa");
@@ -78,8 +78,6 @@ public class RawSubsystemResource implem
private final List<Capability> capabilities;
private final DeploymentManifest deploymentManifest;
- private final File directory;
- private final long id;
private final Repository localRepository;
private final Location location;
private final List<Requirement> requirements;
@@ -90,19 +88,7 @@ public class RawSubsystemResource implem
this.location = new Location(location);
if (content == null)
content = this.location.open();
- id = SubsystemIdentifier.getNextId();
- directory = new File(Activator.getInstance().getBundleContext().getDataFile(""), Long.toString(id));
- if (!directory.mkdir())
- throw new SubsystemException("Unable to make directory " + directory.getAbsolutePath());
- File file = new File(directory, Long.toString(id) + ".ssa");
- FileOutputStream fos = new FileOutputStream(file);
- try {
- IOUtils.copy(content, fos);
- }
- finally {
- IOUtils.close(fos);
- }
- IDirectory idir = FileSystem.getFSRoot(file);
+ IDirectory idir = FileSystem.getFSRoot(content);
try {
resources = computeResources(idir);
localRepository = computeLocalRepository();
@@ -117,6 +103,20 @@ public class RawSubsystemResource implem
IOUtils.close(idir.toCloseable());
}
}
+
+ public RawSubsystemResource(File file) throws IOException, URISyntaxException, ResolutionException {
+ this(FileSystem.getFSRoot(file));
+ }
+
+ public RawSubsystemResource(IDirectory idir) throws IOException, URISyntaxException, ResolutionException {
+ resources = Collections.emptyList();
+ localRepository = computeLocalRepository();
+ subsystemManifest = initializeSubsystemManifest(idir);
+ requirements = subsystemManifest.toRequirements(this);
+ capabilities = subsystemManifest.toCapabilities(this);
+ deploymentManifest = initializeDeploymentManifest(idir);
+ location = new Location(deploymentManifest.getHeaders().get(DeploymentManifest.ARIESSUBSYSTEM_LOCATION).getValue());
+ }
@Override
public List<Capability> getCapabilities(String namespace) {
@@ -134,14 +134,6 @@ public class RawSubsystemResource implem
return deploymentManifest;
}
- public File getDirectory() {
- return directory;
- }
-
- public long getId() {
- return id;
- }
-
public Repository getLocalRepository() {
return localRepository;
}
@@ -288,7 +280,7 @@ public class RawSubsystemResource implem
return new DependencyCalculator(resources).calculateDependencies();
}
- private Collection<Resource> computeResources(IDirectory directory) throws IOException, URISyntaxException, UnsupportedOperationException, ResolutionException {
+ private Collection<Resource> computeResources(IDirectory directory) throws IOException, URISyntaxException, ResolutionException {
List<IFile> files = directory.listFiles();
if (files.isEmpty())
return Collections.emptyList();
@@ -343,6 +335,39 @@ public class RawSubsystemResource implem
return header;
}
+ private DeploymentManifest initializeDeploymentManifest(IDirectory idir)
+ throws IOException {
+ Manifest manifest = ManifestProcessor.obtainManifestFromAppDir(idir,
+ "OSGI-INF/DEPLOYMENT.MF");
+ if (manifest != null)
+ return new DeploymentManifest(manifest);
+ else
+ return new DeploymentManifest.Builder()
+ .manifest(getSubsystemManifest())
+ .location(AriesSubsystem.ROOT_LOCATION).autostart(true).id(0)
+ .lastId(SubsystemIdentifier.getLastId())
+ .region(AriesSubsystem.ROOT_REGION).state(State.INSTALLING)
+ .build();
+ }
+
+ private SubsystemManifest initializeSubsystemManifest(IDirectory idir)
+ throws IOException {
+ Manifest manifest = ManifestProcessor.obtainManifestFromAppDir(idir,
+ "OSGI-INF/SUBSYSTEM.MF");
+ if (manifest != null)
+ return new SubsystemManifest(manifest);
+ else
+ return new SubsystemManifest.Builder()
+ .symbolicName(AriesSubsystem.ROOT_SYMBOLIC_NAME)
+ .version(AriesSubsystem.ROOT_VERSION)
+ .type(SubsystemTypeHeader.TYPE_APPLICATION
+ + ';'
+ + SubsystemTypeHeader.DIRECTIVE_PROVISION_POLICY
+ + ":="
+ + SubsystemTypeHeader.PROVISION_POLICY_ACCEPT_DEPENDENCIES)
+ .build();
+ }
+
private boolean isComposite(SubsystemManifest manifest) {
return SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE.equals(manifest.getSubsystemTypeHeader().getType());
}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/RegionContextBundleHelper.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/RegionContextBundleHelper.java?rev=1353319&r1=1353318&r2=1353319&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/RegionContextBundleHelper.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/RegionContextBundleHelper.java Sun Jun 24 19:48:40 2012
@@ -21,11 +21,11 @@ public class RegionContextBundleHelper {
String symbolicName = SYMBOLICNAME_PREFIX + subsystem.getSubsystemId();
String location = subsystem.getLocation() + '/' + subsystem.getSubsystemId();
Bundle b = subsystem.getRegion().getBundle(symbolicName, VERSION);
- if (b != null)
- return;
- ThreadLocalSubsystem.set(subsystem);
- b = subsystem.getRegion().installBundleAtLocation(location, createRegionContextBundle(symbolicName));
- subsystem.installResource(b.adapt(BundleRevision.class));
+ if (b == null) {
+ ThreadLocalSubsystem.set(subsystem);
+ b = subsystem.getRegion().installBundleAtLocation(location, createRegionContextBundle(symbolicName));
+ }
+ Utils.installResource(b.adapt(BundleRevision.class), subsystem);
// The region context bundle must be started persistently.
b.start();
}
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=1353319&r1=1353318&r2=1353319&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 Sun Jun 24 19:48:40 2012
@@ -1,10 +1,25 @@
package org.apache.aries.subsystem.core.internal;
+import org.osgi.framework.namespace.IdentityNamespace;
import org.osgi.resource.Resource;
import org.osgi.service.coordinator.Coordination;
import org.osgi.service.coordinator.Participant;
+import org.osgi.service.subsystem.SubsystemConstants;
+import org.osgi.service.subsystem.SubsystemException;
public abstract class ResourceInstaller {
+ public static ResourceInstaller newInstance(Coordination coordination, Resource resource, AriesSubsystem subsystem, boolean transitive) {
+ String type = ResourceHelper.getTypeAttribute(resource);
+ if (SubsystemConstants.SUBSYSTEM_TYPE_APPLICATION.equals(type)
+ || SubsystemConstants.SUBSYSTEM_TYPE_COMPOSITE.equals(type)
+ || SubsystemConstants.SUBSYSTEM_TYPE_FEATURE.equals(type))
+ return new SubsystemResourceInstaller(coordination, resource, subsystem, transitive);
+ else if (IdentityNamespace.TYPE_BUNDLE.equals(type) || IdentityNamespace.TYPE_FRAGMENT.equals(type))
+ return new BundleResourceInstaller(coordination, resource, subsystem, transitive);
+ else
+ throw new SubsystemException("No installer exists for resource type: " + type);
+ }
+
protected final Coordination coordination;
protected final AriesSubsystem provisionTo;
protected final Resource resource;
@@ -14,13 +29,21 @@ public abstract class ResourceInstaller
this.coordination = coordination;
this.resource = resource;
this.subsystem = subsystem;
- if (transitive)
- provisionTo = Utils.findFirstSubsystemAcceptingDependenciesStartingFrom(subsystem);
+ if (transitive) {
+ if (Utils.isInstallableResource(resource))
+ provisionTo = Utils.findFirstSubsystemAcceptingDependenciesStartingFrom(subsystem);
+ else
+ provisionTo = null;
+ }
else
provisionTo = subsystem;
}
+ public abstract Resource install() throws Exception;
+
protected void addConstituent(final Resource resource) {
+ if (provisionTo == null)
+ return;
Activator.getInstance().getSubsystems().addConstituent(provisionTo, resource);
coordination.addParticipant(new Participant() {
@Override
@@ -36,6 +59,8 @@ public abstract class ResourceInstaller
}
protected void addReference(final Resource resource) {
+ if (subsystem == null)
+ return;
Activator.getInstance().getSubsystems().addReference(subsystem, resource);
coordination.addParticipant(new Participant() {
@Override
@@ -53,12 +78,4 @@ public abstract class ResourceInstaller
protected String getLocation() {
return provisionTo.getSubsystemId() + "@" + provisionTo.getSymbolicName() + "@" + ResourceHelper.getSymbolicNameAttribute(resource);
}
-
- protected void removeConstituent() {
- Activator.getInstance().getSubsystems().removeConstituent(provisionTo, resource);
- }
-
- protected void removeReference() {
- Activator.getInstance().getSubsystems().removeReference(subsystem, resource);
- }
}
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=1353319&r1=1353318&r2=1353319&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 Sun Jun 24 19:48:40 2012
@@ -53,7 +53,7 @@ public abstract class ResourceUninstalle
protected boolean isTransitive() {
if (subsystem == null)
return false;
- ProvisionResourceHeader header = subsystem.getArchive().getDeploymentManifest().getProvisionResourceHeader();
+ ProvisionResourceHeader header = subsystem.getDeploymentManifest().getProvisionResourceHeader();
if (header == null)
return false;
return header.contains(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=1353319&r1=1353318&r2=1353319&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 Sun Jun 24 19:48:40 2012
@@ -1,21 +1,46 @@
package org.apache.aries.subsystem.core.internal;
-import java.security.PrivilegedAction;
+import java.io.IOException;
+import java.net.URISyntaxException;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.Map.Entry;
+import org.apache.aries.subsystem.core.archive.ExportPackageCapability;
+import org.apache.aries.subsystem.core.archive.ExportPackageHeader;
+import org.apache.aries.subsystem.core.archive.ProvideCapabilityCapability;
+import org.apache.aries.subsystem.core.archive.ProvideCapabilityHeader;
+import org.apache.aries.subsystem.core.archive.SubsystemContentHeader;
+import org.apache.aries.subsystem.core.archive.SubsystemExportServiceCapability;
+import org.apache.aries.subsystem.core.archive.SubsystemExportServiceHeader;
+import org.eclipse.equinox.region.Region;
+import org.eclipse.equinox.region.RegionFilter;
+import org.eclipse.equinox.region.RegionFilterBuilder;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.FrameworkWiring;
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.coordinator.Participant;
+import org.osgi.service.resolver.ResolutionException;
+import org.osgi.service.subsystem.Subsystem;
import org.osgi.service.subsystem.Subsystem.State;
+import org.osgi.service.subsystem.SubsystemConstants;
+import org.osgi.service.subsystem.SubsystemException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-public class StartAction implements PrivilegedAction<Object> {
- private final AriesSubsystem subsystem;
+public class StartAction extends AbstractAction {
+ private static final Logger logger = LoggerFactory.getLogger(AriesSubsystem.class);
public StartAction(AriesSubsystem subsystem) {
- this.subsystem = subsystem;
+ super(subsystem);
}
@Override
@@ -24,16 +49,16 @@ public class StartAction implements Priv
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();
+ 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();
+ resolve(subsystem);
subsystem.setState(State.STARTING);
- subsystem.autostart = true;
+ subsystem.setAutostart(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.
@@ -42,10 +67,11 @@ public class StartAction implements Priv
.create(subsystem.getSymbolicName() + '-' + subsystem.getSubsystemId(), 0);
try {
List<Resource> resources = new ArrayList<Resource>(Activator.getInstance().getSubsystems().getResourcesReferencedBy(subsystem));
- if (!subsystem.isRoot())
- Collections.sort(resources, new StartResourceComparator(subsystem.getSubsystemManifest().getSubsystemContentHeader()));
+ SubsystemContentHeader header = subsystem.getSubsystemManifest().getSubsystemContentHeader();
+ if (header != null && !subsystem.isRoot())
+ Collections.sort(resources, new StartResourceComparator(header));
for (Resource resource : resources)
- subsystem.startResource(resource, coordination);
+ startResource(resource, coordination);
subsystem.setState(State.ACTIVE);
} catch (Throwable t) {
coordination.fail(t);
@@ -64,4 +90,162 @@ public class StartAction implements Priv
}
return null;
}
+
+ private Collection<Bundle> getBundles(AriesSubsystem subsystem) {
+ Collection<Resource> constituents = Activator.getInstance().getSubsystems().getConstituents(subsystem);
+ ArrayList<Bundle> result = new ArrayList<Bundle>(constituents.size());
+ for (Resource resource : constituents) {
+ if (resource instanceof BundleRevision)
+ result.add(((BundleRevision)resource).getBundle());
+ }
+ result.trimToSize();
+ return result;
+ }
+
+ private void resolve(AriesSubsystem subsystem) {
+ if (subsystem.getState() != State.INSTALLED)
+ return;
+ subsystem.setState(State.RESOLVING);
+ try {
+ for (Subsystem child : Activator.getInstance().getSubsystems().getChildren(subsystem))
+ resolve((AriesSubsystem)child);
+ // TODO I think this is insufficient. Do we need both
+ // pre-install and post-install environments for the Resolver?
+ Collection<Bundle> bundles = getBundles(subsystem);
+ if (!Activator.getInstance().getBundleContext().getBundle(0)
+ .adapt(FrameworkWiring.class).resolveBundles(bundles)) {
+ logger.error(
+ "Unable to resolve bundles for subsystem/version/id {}/{}/{}: {}",
+ new Object[] { subsystem.getSymbolicName(), subsystem.getVersion(),
+ subsystem.getSubsystemId(), bundles });
+ throw new SubsystemException("Framework could not resolve the bundles");
+ }
+ setExportIsolationPolicy(subsystem);
+ // TODO Could avoid calling setState (and notifyAll) here and
+ // avoid the need for a lock.
+ subsystem.setState(State.RESOLVED);
+ }
+ catch (Throwable t) {
+ subsystem.setState(State.INSTALLED);
+ if (t instanceof SubsystemException)
+ throw (SubsystemException)t;
+ throw new SubsystemException(t);
+ }
+ }
+
+ private void setExportIsolationPolicy(AriesSubsystem subsystem) throws InvalidSyntaxException, IOException, BundleException, URISyntaxException, ResolutionException {
+ if (subsystem.isRoot())
+ // Nothing to do if this is the root subsystem.
+ return;
+ if (!subsystem.isScoped())
+ // Features share the same isolation as that of their scoped parent.
+ return;
+ Region from = ((AriesSubsystem)subsystem.getParents().iterator().next()).getRegion();
+ Region to = subsystem.getRegion();
+ RegionFilterBuilder builder = from.getRegionDigraph().createRegionFilterBuilder();
+ if (subsystem.isComposite()) {
+ setExportIsolationPolicy(builder, subsystem.getDeploymentManifest().getExportPackageHeader(), subsystem);
+ setExportIsolationPolicy(builder, subsystem.getDeploymentManifest().getProvideCapabilityHeader(), subsystem);
+ setExportIsolationPolicy(builder, subsystem.getDeploymentManifest().getSubsystemExportServiceHeader(), subsystem);
+ // TODO Implement export isolation policy for composites.
+ }
+ RegionFilter regionFilter = builder.build();
+ if (logger.isDebugEnabled())
+ logger.debug("Establishing region connection: from=" + from
+ + ", to=" + to + ", filter=" + regionFilter);
+ from.connectRegion(to, regionFilter);
+ }
+
+ private void setExportIsolationPolicy(RegionFilterBuilder builder, ExportPackageHeader header, AriesSubsystem subsystem) throws InvalidSyntaxException {
+ if (header == null)
+ return;
+ String policy = RegionFilter.VISIBLE_PACKAGE_NAMESPACE;
+ for (ExportPackageCapability capability : header.toCapabilities(subsystem)) {
+ StringBuilder filter = new StringBuilder("(&");
+ for (Entry<String, Object> attribute : capability.getAttributes().entrySet())
+ filter.append('(').append(attribute.getKey()).append('=').append(attribute.getValue()).append(')');
+ filter.append(')');
+ if (logger.isDebugEnabled())
+ logger.debug("Allowing " + policy + " of " + filter);
+ builder.allow(policy, filter.toString());
+ }
+ }
+
+ private void setExportIsolationPolicy(RegionFilterBuilder builder, ProvideCapabilityHeader header, AriesSubsystem subsystem) throws InvalidSyntaxException {
+ if (header == null)
+ return;
+ for (ProvideCapabilityHeader.Clause clause : header.getClauses()) {
+ ProvideCapabilityCapability capability = new ProvideCapabilityCapability(clause, subsystem);
+ String policy = capability.getNamespace();
+ StringBuilder filter = new StringBuilder("(&");
+ for (Entry<String, Object> attribute : capability.getAttributes().entrySet())
+ filter.append('(').append(attribute.getKey()).append('=').append(attribute.getValue()).append(')');
+ filter.append(')');
+ if (logger.isDebugEnabled())
+ logger.debug("Allowing " + policy + " of " + filter);
+ builder.allow(policy, filter.toString());
+ }
+ }
+
+ private void setExportIsolationPolicy(RegionFilterBuilder builder, SubsystemExportServiceHeader header, AriesSubsystem subsystem) throws InvalidSyntaxException {
+ if (header == null)
+ return;
+ String policy = RegionFilter.VISIBLE_SERVICE_NAMESPACE;
+ for (SubsystemExportServiceHeader.Clause clause : header.getClauses()) {
+ SubsystemExportServiceCapability capability = new SubsystemExportServiceCapability(clause, subsystem);
+ String filter = capability.getDirectives().get(SubsystemExportServiceCapability.DIRECTIVE_FILTER);
+ if (logger.isDebugEnabled())
+ logger.debug("Allowing " + policy + " of " + filter);
+ builder.allow(policy, filter.toString());
+ }
+ }
+
+ private void startBundleResource(Resource resource, Coordination coordination) throws BundleException {
+ final Bundle bundle = ((BundleRevision)resource).getBundle();
+ if ((bundle.getState() & (Bundle.STARTING | Bundle.ACTIVE)) != 0)
+ return;
+ bundle.start(Bundle.START_TRANSIENT | Bundle.START_ACTIVATION_POLICY);
+ 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))
+ startSubsystemResource(resource, coordination);
+ else if (IdentityNamespace.TYPE_BUNDLE.equals(type))
+ startBundleResource(resource, coordination);
+ else if (IdentityNamespace.TYPE_FRAGMENT.equals(type)) {
+ // Fragments are not started.
+ }
+ else
+ throw new SubsystemException("Unsupported resource type: " + type);
+ }
+
+ private void startSubsystemResource(Resource resource, Coordination coordination) throws IOException {
+ final AriesSubsystem subsystem = (AriesSubsystem)resource;
+ subsystem.start();
+ if (coordination == null)
+ return;
+ coordination.addParticipant(new Participant() {
+ public void ended(Coordination coordination) throws Exception {
+ // noop
+ }
+
+ public void failed(Coordination coordination) throws Exception {
+ subsystem.stop();
+ }
+ });
+ }
}
Added: 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=1353319&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StopAction.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/StopAction.java Sun Jun 24 19:48:40 2012
@@ -0,0 +1,108 @@
+package org.apache.aries.subsystem.core.internal;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+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.namespace.IdentityNamespace;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.resource.Resource;
+import org.osgi.service.subsystem.Subsystem.State;
+import org.osgi.service.subsystem.SubsystemConstants;
+import org.osgi.service.subsystem.SubsystemException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class StopAction extends AbstractAction {
+ private static final Logger logger = LoggerFactory.getLogger(StopAction.class);
+
+ public StopAction(AriesSubsystem subsystem) {
+ super(subsystem);
+ }
+
+ public StopAction(AriesSubsystem subsystem, boolean disableRootCheck) {
+ super(subsystem, disableRootCheck);
+ }
+
+ @Override
+ public Object run() {
+ checkRoot();
+ subsystem.setAutostart(false);
+ if (subsystem.getState() == State.UNINSTALLING || subsystem.getState() == State.UNINSTALLED) {
+ throw new SubsystemException("Cannot stop from state " + subsystem.getState());
+ }
+ else if (subsystem.getState() == State.STARTING) {
+ waitForStateChange();
+ subsystem.stop();
+ }
+ else if (subsystem.getState() != State.ACTIVE) {
+ return null;
+ }
+ subsystem.setState(State.STOPPING);
+ // For non-root subsystems, stop any remaining constituents.
+ if (!subsystem.isRoot()){
+ List<Resource> resources = new ArrayList<Resource>(Activator.getInstance().getSubsystems().getResourcesReferencedBy(subsystem));
+ SubsystemContentHeader header = subsystem.getSubsystemManifest().getSubsystemContentHeader();
+ if (header != null) {
+ Collections.sort(resources, new StartResourceComparator(subsystem.getSubsystemManifest().getSubsystemContentHeader()));
+ Collections.reverse(resources);
+ }
+ for (Resource resource : resources) {
+ // Don't stop the region context bundle.
+ if (ResourceHelper.getSymbolicNameAttribute(resource).startsWith(RegionContextBundleHelper.SYMBOLICNAME_PREFIX))
+ continue;
+ try {
+ stopResource(resource);
+ }
+ catch (Exception e) {
+ logger.error("An error occurred while stopping resource " + resource + " of subsystem " + subsystem, e);
+ }
+ }
+ }
+ // TODO Can we automatically assume it actually is resolved?
+ subsystem.setState(State.RESOLVED);
+ try {
+ subsystem.setDeploymentManifest(new DeploymentManifest(
+ subsystem.getDeploymentManifest(),
+ null,
+ subsystem.isAutostart(),
+ subsystem.getSubsystemId(),
+ SubsystemIdentifier.getLastId(),
+ subsystem.getLocation(),
+ false,
+ false));
+ }
+ catch (Exception e) {
+ throw new SubsystemException(e);
+ }
+ return null;
+ }
+
+ private void stopBundleResource(Resource resource) throws BundleException {
+ ((BundleRevision)resource).getBundle().stop();
+ }
+
+ private void stopResource(Resource resource) throws BundleException, IOException {
+ if (Utils.getActiveUseCount(resource) >= 1)
+ 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))
+ stopSubsystemResource(resource);
+ else if (IdentityNamespace.TYPE_BUNDLE.equals(type))
+ stopBundleResource(resource);
+ else if (IdentityNamespace.TYPE_FRAGMENT.equals(type))
+ return;
+ else
+ throw new SubsystemException("Unsupported resource type: " + type);
+ }
+
+ private void stopSubsystemResource(Resource resource) throws IOException {
+ ((AriesSubsystem)resource).stop();
+ }
+}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHook.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHook.java?rev=1353319&r1=1353318&r2=1353319&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHook.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResolverHook.java Sun Jun 24 19:48:40 2012
@@ -47,7 +47,7 @@ public class SubsystemResolverHook imple
Collection<BundleCapability> preferredProviders = new ArrayList<BundleCapability>(candidates.size());
for (BundleCapability candidate : candidates)
for (AriesSubsystem subsystem : requirers) {
- PreferredProviderHeader header = subsystem.getArchive().getSubsystemManifest().getPreferredProviderHeader();
+ PreferredProviderHeader header = subsystem.getSubsystemManifest().getPreferredProviderHeader();
if (header != null && (header.contains(candidate.getResource()) || isResourceConstituentOfPreferredSubsystem(candidate.getResource(), subsystem)))
preferredProviders.add(candidate);
}
@@ -89,7 +89,7 @@ public class SubsystemResolverHook imple
private boolean isResourceConstituentOfPreferredSubsystem(Resource resource, AriesSubsystem preferer) {
Collection<AriesSubsystem> subsystems = Activator.getInstance().getSubsystems().getSubsystemsReferencing(resource);
for (AriesSubsystem subsystem : subsystems)
- if (preferer.getArchive().getSubsystemManifest().getPreferredProviderHeader().contains(subsystem))
+ if (preferer.getSubsystemManifest().getPreferredProviderHeader().contains(subsystem))
return true;
return false;
}
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=1353319&r1=1353318&r2=1353319&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 Sun Jun 24 19:48:40 2012
@@ -11,26 +11,51 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import org.apache.aries.subsystem.core.archive.Attribute;
import org.apache.aries.subsystem.core.archive.DeployedContentHeader;
import org.apache.aries.subsystem.core.archive.DeploymentManifest;
+import org.apache.aries.subsystem.core.archive.Header;
+import org.apache.aries.subsystem.core.archive.ImportPackageHeader;
+import org.apache.aries.subsystem.core.archive.ImportPackageRequirement;
import org.apache.aries.subsystem.core.archive.ProvisionResourceHeader;
+import org.apache.aries.subsystem.core.archive.RequireBundleHeader;
+import org.apache.aries.subsystem.core.archive.RequireBundleRequirement;
+import org.apache.aries.subsystem.core.archive.RequireCapabilityHeader;
+import org.apache.aries.subsystem.core.archive.RequireCapabilityRequirement;
import org.apache.aries.subsystem.core.archive.SubsystemContentHeader;
+import org.apache.aries.subsystem.core.archive.SubsystemImportServiceHeader;
+import org.apache.aries.subsystem.core.archive.SubsystemImportServiceRequirement;
import org.apache.aries.subsystem.core.archive.SubsystemManifest;
+import org.apache.aries.util.filesystem.FileSystem;
+import org.apache.aries.util.filesystem.IDirectory;
+import org.eclipse.equinox.region.Region;
+import org.eclipse.equinox.region.RegionDigraph;
+import org.eclipse.equinox.region.RegionFilter;
+import org.eclipse.equinox.region.RegionFilterBuilder;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.namespace.IdentityNamespace;
import org.osgi.framework.wiring.BundleRevision;
import org.osgi.resource.Capability;
import org.osgi.resource.Requirement;
import org.osgi.resource.Resource;
import org.osgi.resource.Wire;
import org.osgi.resource.Wiring;
+import org.osgi.service.coordinator.Coordination;
+import org.osgi.service.coordinator.Participant;
import org.osgi.service.repository.Repository;
import org.osgi.service.resolver.HostedCapability;
import org.osgi.service.resolver.ResolutionException;
import org.osgi.service.resolver.ResolveContext;
+import org.osgi.service.subsystem.Subsystem;
import org.osgi.service.subsystem.SubsystemConstants;
import org.osgi.service.subsystem.SubsystemException;
public class SubsystemResource implements Resource {
+ private Region region;
+
private final DeploymentManifest deploymentManifest;
+ private final long id;
private final Collection<Resource> installableContent = new HashSet<Resource>();
private final Collection<Resource> installableDependencies = new HashSet<Resource>();
private final Collection<Resource> mandatoryResources = new HashSet<Resource>();
@@ -48,11 +73,26 @@ public class SubsystemResource implement
public SubsystemResource(RawSubsystemResource resource, AriesSubsystem parent) throws IOException {
this.parent = parent;
this.resource = resource;
+ id = SubsystemIdentifier.getNextId();
preferredProviderRepository = new PreferredProviderRepository(this);
- computeContentResources();
- computeDependencies();
+ computeContentResources(resource.getDeploymentManifest());
+ computeDependencies(resource.getDeploymentManifest());
deploymentManifest = computeDeploymentManifest();
}
+
+ public SubsystemResource(File file) throws IOException, URISyntaxException, ResolutionException {
+ this(FileSystem.getFSRoot(file));
+ }
+
+ public SubsystemResource(IDirectory directory) throws IOException, URISyntaxException, ResolutionException {
+ parent = null;
+ resource = new RawSubsystemResource(directory);
+ preferredProviderRepository = null;
+ deploymentManifest = resource.getDeploymentManifest();
+ id = Long.parseLong(deploymentManifest.getHeaders().get(DeploymentManifest.ARIESSUBSYSTEM_ID).getValue());
+ computeContentResources(deploymentManifest);
+ computeDependencies(deploymentManifest);
+ }
@Override
public List<Capability> getCapabilities(String namespace) {
@@ -63,12 +103,8 @@ public class SubsystemResource implement
return deploymentManifest;
}
- public File getDirectory() {
- return resource.getDirectory();
- }
-
public long getId() {
- return resource.getId();
+ return id;
}
public Collection<Resource> getInstallableContent() {
@@ -87,8 +123,38 @@ public class SubsystemResource implement
return resource.getLocation().getValue();
}
- public AriesSubsystem getParent() {
- return parent;
+ public Collection<AriesSubsystem> getParents() {
+ if (parent == null) {
+ Header<?> header = getDeploymentManifest().getHeaders().get(DeploymentManifest.ARIESSUBSYSTEM_PARENTS);
+ if (header == null)
+ return Collections.emptyList();
+ String[] parents = header.getValue().split(",");
+ Collection<AriesSubsystem> result = new ArrayList<AriesSubsystem>(parents.length);
+ for (String parent : parents)
+ result.add(Activator.getInstance().getSubsystems().getSubsystemById(Long.valueOf(parent)));
+ return result;
+ }
+ return Collections.singleton(parent);
+ }
+
+ public synchronized Region getRegion() throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
+ if (region == null) {
+ region = createRegion(getId());
+ Coordination coordination = Activator.getInstance().getCoordinator().peek();
+ coordination.addParticipant(new Participant() {
+ @Override
+ public void ended(Coordination arg0) throws Exception {
+// region.getRegionDigraph().removeRegion(region);
+ }
+
+ @Override
+ public void failed(Coordination arg0) throws Exception {
+ region.getRegionDigraph().removeRegion(region);
+ }
+ });
+ setImportIsolationPolicy();
+ }
+ return region;
}
@Override
@@ -125,7 +191,7 @@ public class SubsystemResource implement
sharedContent.add(resource);
}
- private boolean addDependencies(Repository repository, Requirement requirement, List<Capability> capabilities) {
+ private boolean addDependencies(Repository repository, Requirement requirement, List<Capability> capabilities) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
Map<Requirement, Collection<Capability>> m = repository.findProviders(Collections.singleton(requirement));
if (m.containsKey(requirement)) {
Collection<Capability> cc = m.get(requirement);
@@ -135,26 +201,26 @@ public class SubsystemResource implement
return !capabilities.isEmpty();
}
- private boolean addDependenciesFromContentRepository(Requirement requirement, List<Capability> capabilities) {
+ private boolean addDependenciesFromContentRepository(Requirement requirement, List<Capability> capabilities) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
Repository repository = new ContentRepository(installableContent, sharedContent);
return addDependencies(repository, requirement, capabilities);
}
- private boolean addDependenciesFromLocalRepository(Requirement requirement, List<Capability> 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) {
+ 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) {
+ 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) {
+ private boolean addDependenciesFromSystemRepository(Requirement requirement, List<Capability> capabilities) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
Repository repository = Activator.getInstance().getSystemRepository();
return addDependencies(repository, requirement, capabilities);
}
@@ -168,14 +234,64 @@ public class SubsystemResource implement
sharedDependencies.add(resource);
}
- private void addValidCapabilities(Collection<Capability> from, Collection<Capability> to) {
+ private void addValidCapabilities(Collection<Capability> from, Collection<Capability> to) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
for (Capability c : from)
if (isValid(c))
to.add(c);
}
- private void computeContentResources() {
- SubsystemContentHeader contentHeader = resource.getSubsystemManifest().getSubsystemContentHeader();
+ private void addSubsystemServiceImportToSharingPolicy(
+ RegionFilterBuilder builder) throws InvalidSyntaxException, BundleException, IOException, URISyntaxException {
+ builder.allow(
+ RegionFilter.VISIBLE_SERVICE_NAMESPACE,
+ new StringBuilder("(&(")
+ .append(org.osgi.framework.Constants.OBJECTCLASS)
+ .append('=').append(Subsystem.class.getName())
+ .append(")(")
+ .append(Constants.SubsystemServicePropertyRegions)
+ .append('=').append(getRegion().getName())
+ .append("))").toString());
+ }
+
+ private void addSubsystemServiceImportToSharingPolicy(RegionFilterBuilder builder, Region to)
+ throws InvalidSyntaxException, BundleException, IOException, URISyntaxException {
+ if (to.getName().equals(AriesSubsystem.ROOT_REGION))
+ addSubsystemServiceImportToSharingPolicy(builder);
+ else {
+ to = Activator.getInstance().getSubsystems().getRootSubsystem().getRegion();
+ builder = to.getRegionDigraph().createRegionFilterBuilder();
+ addSubsystemServiceImportToSharingPolicy(builder);
+ RegionFilter regionFilter = builder.build();
+ getRegion().connectRegion(to, regionFilter);
+ }
+ }
+
+ private void computeContentResources(DeploymentManifest manifest) {
+ if (manifest == null)
+ computeContentResources(getSubsystemManifest());
+ else {
+ DeployedContentHeader header = manifest.getDeployedContentHeader();
+ if (header == null)
+ return;
+ for (DeployedContentHeader.Clause clause : header.getClauses()) {
+ Resource resource = findContent(clause);
+ if (resource == null)
+ throw new SubsystemException("Resource does not exist: " + clause);
+ addContentResource(resource);
+ }
+ }
+// if (parent == null) {
+// if (deploymentManifest == null)
+// return;
+// computeContentResourcesFromDeploymentManifest();
+// }
+// else {
+// computeContentResourcesFromSubsystemManifest();
+// }
+ }
+
+ private void computeContentResources(SubsystemManifest manifest) {
+ SubsystemContentHeader contentHeader = manifest.getSubsystemContentHeader();
if (contentHeader == null)
return;
for (SubsystemContentHeader.Content content : contentHeader.getContents()) {
@@ -192,8 +308,49 @@ public class SubsystemResource implement
}
}
- private void computeDependencies() {
- SubsystemContentHeader contentHeader = resource.getSubsystemManifest().getSubsystemContentHeader();
+ private void computeDependencies(DeploymentManifest manifest) {
+ if (manifest == null)
+ computeDependencies(getSubsystemManifest());
+ else {
+ ProvisionResourceHeader header = manifest.getProvisionResourceHeader();
+ if (header == null)
+ return;
+ for (ProvisionResourceHeader.ProvisionedResource provisionedResource : header.getProvisionedResources()) {
+ Resource resource = findDependency(provisionedResource);
+ if (resource == null)
+ throw new SubsystemException("Resource does not exist: " + provisionedResource);
+ addDependency(resource);
+ }
+ }
+// if (parent == null) {
+// if (deploymentManifest == null)
+// return;
+// ProvisionResourceHeader header = deploymentManifest.getProvisionResourceHeader();
+// if (header == null)
+// return;
+// for (ProvisionResourceHeader.ProvisionedResource provisionedResource : header.getProvisionedResources()) {
+// Resource resource = findDependency(provisionedResource);
+// if (resource == null)
+// throw new SubsystemException("Resource does not exist: " + provisionedResource);
+// addContentResource(resource);
+// }
+// }
+// else {
+// SubsystemContentHeader contentHeader = resource.getSubsystemManifest().getSubsystemContentHeader();
+// try {
+// Map<Resource, List<Wire>> resolution = Activator.getInstance().getResolver().resolve(createResolveContext());
+// for (Resource resource : resolution.keySet())
+// if (!contentHeader.contains(resource))
+// addDependency(resource);
+// }
+// catch (ResolutionException e) {
+// throw new SubsystemException(e);
+// }
+// }
+ }
+
+ private void computeDependencies(SubsystemManifest manifest) {
+ SubsystemContentHeader contentHeader = manifest.getSubsystemContentHeader();
try {
Map<Resource, List<Wire>> resolution = Activator.getInstance().getResolver().resolve(createResolveContext());
for (Resource resource : resolution.keySet())
@@ -233,21 +390,53 @@ public class SubsystemResource implement
return ProvisionResourceHeader.newInstance(dependencies);
}
+ private Region createRegion(long id) throws BundleException {
+ if (!isScoped())
+ return getParents().iterator().next().getRegion();
+ Activator activator = Activator.getInstance();
+ RegionDigraph digraph = activator.getRegionDigraph();
+ if (getParents().isEmpty())
+ return digraph.getRegion(AriesSubsystem.ROOT_REGION);
+ String name = getSubsystemManifest()
+ .getSubsystemSymbolicNameHeader().getSymbolicName()
+ + ';'
+ + getSubsystemManifest().getSubsystemVersionHeader()
+ .getVersion()
+ + ';'
+ + getSubsystemManifest().getSubsystemTypeHeader()
+ .getType() + ';' + Long.toString(id);
+ Region region = digraph.getRegion(name);
+ // TODO New regions need to be cleaned up if this subsystem fails to
+ // install, but there's no access to the coordination here.
+ if (region == null)
+ return digraph.createRegion(name);
+ return region;
+ }
+
private ResolveContext createResolveContext() {
return new ResolveContext() {
@Override
public List<Capability> findProviders(Requirement requirement) {
List<Capability> result = new ArrayList<Capability>();
- if (addDependenciesFromContentRepository(requirement, result))
- return result;
- if (addDependenciesFromPreferredProviderRepository(requirement, result))
- return result;
- if (addDependenciesFromSystemRepository(requirement, result))
- return result;
- if (addDependenciesFromLocalRepository(requirement, result))
- return result;
- if (addDependenciesFromRepositoryServiceRepositories(requirement, result))
- return result;
+ try {
+ if (addDependenciesFromContentRepository(requirement, result))
+ return result;
+ if (addDependenciesFromPreferredProviderRepository(requirement, result))
+ return result;
+ if (addDependenciesFromSystemRepository(requirement, result))
+ return result;
+ if (addDependenciesFromLocalRepository(requirement, result))
+ return result;
+ if (addDependenciesFromRepositoryServiceRepositories(requirement, result))
+ return result;
+ }
+ catch (Throwable t) {
+ if (t instanceof SubsystemException)
+ throw (SubsystemException)t;
+ if (t instanceof SecurityException)
+ throw (SecurityException)t;
+ throw new SubsystemException(t);
+ }
return result;
}
@@ -308,6 +497,41 @@ public class SubsystemResource implement
return null;
}
+ private Resource findContent(DeployedContentHeader.Clause clause) {
+ Attribute attribute = clause.getAttribute(DeployedContentHeader.Clause.ATTRIBUTE_RESOURCEID);
+ long resourceId = attribute == null ? -1 : Long.parseLong(String.valueOf(attribute.getValue()));
+ if (resourceId != -1) {
+ String type = clause.getType();
+ if (IdentityNamespace.TYPE_BUNDLE.equals(type) || IdentityNamespace.TYPE_FRAGMENT.equals(type)) {
+ return Activator.getInstance().getBundleContext().getBundle(0).getBundleContext().getBundle(resourceId).adapt(BundleRevision.class);
+ }
+ else
+ return Activator.getInstance().getSubsystems().getSubsystemById(resourceId);
+ }
+ OsgiIdentityRequirement requirement = new OsgiIdentityRequirement(
+ clause.getPath(), clause.getDeployedVersion(),
+ clause.getType(), false);
+ return findContent(requirement);
+ }
+
+ private Resource findDependency(ProvisionResourceHeader.ProvisionedResource provisionedResource) {
+ long resourceId = provisionedResource.getResourceId();
+ if (resourceId != -1) {
+ String type = provisionedResource.getNamespace();
+ if (IdentityNamespace.TYPE_BUNDLE.equals(type) || IdentityNamespace.TYPE_FRAGMENT.equals(type))
+ return Activator.getInstance().getBundleContext().getBundle(0).getBundleContext().getBundle(resourceId).adapt(BundleRevision.class);
+ else
+ return Activator.getInstance().getSubsystems().getSubsystemById(resourceId);
+ }
+ OsgiIdentityRequirement requirement = new OsgiIdentityRequirement(
+ provisionedResource.getName(), provisionedResource.getDeployedVersion(),
+ provisionedResource.getNamespace(), false);
+ List<Capability> capabilities = createResolveContext().findProviders(requirement);
+ if (capabilities.isEmpty())
+ return null;
+ return capabilities.get(0).getResource();
+ }
+
private Collection<Resource> getContentResources() {
Collection<Resource> result = new ArrayList<Resource>(installableContent.size() + sharedContent.size());
result.addAll(installableContent);
@@ -322,6 +546,10 @@ public class SubsystemResource implement
return result;
}
+ private boolean isContent(Resource resource) {
+ return getSubsystemManifest().getSubsystemContentHeader().contains(resource);
+ }
+
private boolean isInstallable(Resource resource) {
return !isShared(resource);
}
@@ -333,8 +561,12 @@ public class SubsystemResource implement
return header.isMandatory(resource);
}
+ private boolean isRoot() {
+ return AriesSubsystem.ROOT_LOCATION.equals(getLocation());
+ }
+
private boolean isShared(Resource resource) {
- return resource instanceof AriesSubsystem || resource instanceof BundleRevision;
+ return Utils.isSharedResource(resource);
}
private boolean isScoped() {
@@ -347,12 +579,91 @@ public class SubsystemResource implement
return !isScoped();
}
- private boolean isValid(Capability capability) {
- AriesSubsystem subsystem;
- if (isInstallable(capability.getResource()))
- subsystem = Utils.findFirstSubsystemAcceptingDependenciesStartingFrom(parent);
+ private boolean isValid(Capability capability) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
+ if (IdentityNamespace.IDENTITY_NAMESPACE.equals(capability.getNamespace()))
+ return true;
+ Region region;
+ if (isInstallable(capability.getResource())) {
+ if (isContent(capability.getResource()))
+ region = getRegion();
+ else
+ region = Utils.findFirstSubsystemAcceptingDependenciesStartingFrom(parent).getRegion();
+ }
else
- subsystem = Activator.getInstance().getSubsystems().getSubsystemsReferencing(capability.getResource()).iterator().next();
- return new SharingPolicyValidator(subsystem.getRegion(), parent.getRegion()).isValid(capability);
+ region = Activator.getInstance().getSubsystems().getSubsystemsReferencing(capability.getResource()).iterator().next().getRegion();
+ return new SharingPolicyValidator(region, getRegion()).isValid(capability);
+ }
+
+ 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 = ((AriesSubsystem)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()) {
+ // Both applications and composites have Import-Package headers that require processing.
+ // In the case of applications, the header is generated.
+ Header<?> header = getSubsystemManifest().getImportPackageHeader();
+ setImportIsolationPolicy(builder, (ImportPackageHeader)header);
+ // Both applications and composites have Require-Capability headers that require processing.
+ // In the case of applications, the header is generated.
+ header = getSubsystemManifest().getRequireCapabilityHeader();
+ setImportIsolationPolicy(builder, (RequireCapabilityHeader)header);
+ // Both applications and composites have Subsystem-ImportService headers that require processing.
+ // In the case of applications, the header is generated.
+ header = getSubsystemManifest().getSubsystemImportServiceHeader();
+ setImportIsolationPolicy(builder, (SubsystemImportServiceHeader)header);
+ header = getSubsystemManifest().getRequireBundleHeader();
+ setImportIsolationPolicy(builder, (RequireBundleHeader)header);
+ }
+ RegionFilter regionFilter = builder.build();
+ from.connectRegion(to, regionFilter);
+ }
+
+ private void setImportIsolationPolicy(RegionFilterBuilder builder, ImportPackageHeader header) throws InvalidSyntaxException {
+ if (header == null)
+ return;
+ String policy = RegionFilter.VISIBLE_PACKAGE_NAMESPACE;
+ for (ImportPackageHeader.Clause clause : header.getClauses()) {
+ ImportPackageRequirement requirement = new ImportPackageRequirement(clause, this);
+ String filter = requirement.getDirectives().get(ImportPackageRequirement.DIRECTIVE_FILTER);
+ builder.allow(policy, filter);
+ }
+ }
+
+ private void setImportIsolationPolicy(RegionFilterBuilder builder, RequireBundleHeader header) throws InvalidSyntaxException {
+ if (header == null)
+ return;
+ for (RequireBundleHeader.Clause clause : header.getClauses()) {
+ RequireBundleRequirement requirement = new RequireBundleRequirement(clause, this);
+ String policy = RegionFilter.VISIBLE_REQUIRE_NAMESPACE;
+ String filter = requirement.getDirectives().get(RequireBundleRequirement.DIRECTIVE_FILTER);
+ builder.allow(policy, filter);
+ }
+ }
+
+ private void setImportIsolationPolicy(RegionFilterBuilder builder, RequireCapabilityHeader header) throws InvalidSyntaxException {
+ if (header == null)
+ return;
+ for (RequireCapabilityHeader.Clause clause : header.getClauses()) {
+ RequireCapabilityRequirement requirement = new RequireCapabilityRequirement(clause, this);
+ String policy = requirement.getNamespace();
+ String filter = requirement.getDirectives().get(RequireCapabilityRequirement.DIRECTIVE_FILTER);
+ builder.allow(policy, filter);
+ }
+ }
+
+ private void setImportIsolationPolicy(RegionFilterBuilder builder, SubsystemImportServiceHeader header) throws InvalidSyntaxException {
+ if (header == null)
+ return;
+ for (SubsystemImportServiceHeader.Clause clause : header.getClauses()) {
+ SubsystemImportServiceRequirement requirement = new SubsystemImportServiceRequirement(clause, this);
+ String policy = RegionFilter.VISIBLE_SERVICE_NAMESPACE;
+ String filter = requirement.getDirectives().get(SubsystemImportServiceRequirement.DIRECTIVE_FILTER);
+ builder.allow(policy, filter);
+ }
}
}
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=1353319&r1=1353318&r2=1353319&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 Sun Jun 24 19:48:40 2012
@@ -1,36 +1,36 @@
package org.apache.aries.subsystem.core.internal;
import java.security.AccessController;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
import org.osgi.resource.Resource;
import org.osgi.service.coordinator.Coordination;
import org.osgi.service.coordinator.Participant;
import org.osgi.service.repository.RepositoryContent;
+import org.osgi.service.subsystem.Subsystem.State;
public class SubsystemResourceInstaller extends ResourceInstaller {
public SubsystemResourceInstaller(Coordination coordination, Resource resource, AriesSubsystem subsystem, boolean transitive) {
super(coordination, resource, subsystem, transitive);
}
- public void install() throws Exception {
- final AriesSubsystem subsystem;
- if (resource instanceof RepositoryContent) {
- AccessController.doPrivileged(new InstallAction(getLocation(), ((RepositoryContent)resource).getContent(), provisionTo, null, coordination, true));
- return;
- }
+ public Resource install() throws Exception {
+ if (resource instanceof RepositoryContent)
+ return installRepositoryContent((RepositoryContent)resource);
else if (resource instanceof AriesSubsystem)
- subsystem = (AriesSubsystem)resource;
+ return installAriesSubsystem((AriesSubsystem)resource);
else if (resource instanceof RawSubsystemResource)
- subsystem = new AriesSubsystem(new SubsystemResource((RawSubsystemResource)resource, provisionTo), provisionTo);
+ return installRawSubsystemResource((RawSubsystemResource)resource);
else
- subsystem = new AriesSubsystem((SubsystemResource)resource, provisionTo);
- addChild(subsystem);
- addConstituent(subsystem);
- addReference(subsystem);
- subsystem.install(coordination, provisionTo);
+ return installSubsystemResource((SubsystemResource)resource);
}
private void addChild(final AriesSubsystem child) {
+ if (provisionTo == null || subsystem == null)
+ return;
Activator.getInstance().getSubsystems().addChild(subsystem, child);
coordination.addParticipant(new Participant() {
@Override
@@ -44,4 +44,173 @@ public class SubsystemResourceInstaller
}
});
}
+
+ private void addSubsystem(final AriesSubsystem subsystem) {
+ Activator.getInstance().getSubsystems().addSubsystem(subsystem);
+ coordination.addParticipant(new Participant() {
+ @Override
+ public void ended(Coordination arg0) throws Exception {
+ // Nothing
+ }
+
+ @Override
+ public void failed(Coordination arg0) throws Exception {
+ Activator.getInstance().getSubsystems().removeSubsystem(subsystem);
+ }
+ });
+ }
+
+// private void addSubsystemServiceImportToSharingPolicy(
+// RegionFilterBuilder builder, AriesSubsystem subsystem) throws InvalidSyntaxException {
+// builder.allow(
+// RegionFilter.VISIBLE_SERVICE_NAMESPACE,
+// new StringBuilder("(&(")
+// .append(org.osgi.framework.Constants.OBJECTCLASS)
+// .append('=').append(Subsystem.class.getName())
+// .append(")(")
+// .append(Constants.SubsystemServicePropertyRegions)
+// .append('=').append(subsystem.getRegion().getName())
+// .append("))").toString());
+// }
+
+// private void addSubsystemServiceImportToSharingPolicy(RegionFilterBuilder builder, Region to, AriesSubsystem subsystem)
+// throws InvalidSyntaxException, BundleException {
+// if (to.getName().equals(AriesSubsystem.ROOT_REGION))
+// addSubsystemServiceImportToSharingPolicy(builder, subsystem);
+// else {
+// to = Activator.getInstance().getSubsystems().getRootSubsystem().getRegion();
+// builder = to.getRegionDigraph().createRegionFilterBuilder();
+// addSubsystemServiceImportToSharingPolicy(builder, subsystem);
+// RegionFilter regionFilter = builder.build();
+// subsystem.getRegion().connectRegion(to, regionFilter);
+// }
+// }
+
+ private Resource installAriesSubsystem(AriesSubsystem subsystem) throws Exception {
+ addChild(subsystem);
+ addConstituent(subsystem);
+ addReference(subsystem);
+ // TODO Is this check really necessary?
+ if (!State.INSTALLING.equals(subsystem.getState()))
+ return subsystem;
+ addSubsystem(subsystem);
+ if (subsystem.isScoped())
+ RegionContextBundleHelper.installRegionContextBundle(subsystem);
+ Activator.getInstance().getSubsystemServiceRegistrar().register(subsystem, this.subsystem);
+ // Set up the sharing policy before installing the resources so that the
+ // environment can filter out capabilities from dependencies being
+ // provisioned to regions that are out of scope. This doesn't hurt
+ // anything since the resources are disabled from resolving anyway.
+// setImportIsolationPolicy(subsystem);
+ if (!subsystem.isRoot()) {
+ Comparator<Resource> comparator = new InstallResourceComparator();
+ // Install dependencies first...
+ List<Resource> dependencies = new ArrayList<Resource>(subsystem.getResource().getInstallableDependencies());
+ Collections.sort(dependencies, comparator);
+ for (Resource dependency : dependencies)
+ ResourceInstaller.newInstance(coordination, dependency, subsystem, true).install();
+ for (Resource dependency : subsystem.getResource().getSharedDependencies())
+ ResourceInstaller.newInstance(coordination, dependency, subsystem, true).install();
+ // ...followed by content.
+ List<Resource> installableContent = new ArrayList<Resource>(subsystem.getResource().getInstallableContent());
+ Collections.sort(installableContent, comparator);
+ for (Resource content : installableContent)
+ ResourceInstaller.newInstance(coordination, content, subsystem, false).install();
+ // Simulate installation of shared content so that necessary relationships are established.
+ for (Resource content : subsystem.getResource().getSharedContent())
+ ResourceInstaller.newInstance(coordination, content, subsystem, false).install();
+ }
+ subsystem.setState(State.INSTALLED);
+ return subsystem;
+ }
+
+ private Resource installRawSubsystemResource(RawSubsystemResource resource) throws Exception {
+ SubsystemResource subsystemResource = new SubsystemResource(resource, provisionTo);
+ return installSubsystemResource(subsystemResource);
+ }
+
+ private Resource installRepositoryContent(RepositoryContent resource) {
+ return AccessController.doPrivileged(new InstallAction(getLocation(), resource.getContent(), provisionTo, null, coordination, true));
+ }
+
+ private Resource installSubsystemResource(SubsystemResource resource) throws Exception {
+ AriesSubsystem subsystem = new AriesSubsystem(resource);
+ installAriesSubsystem(subsystem);
+ if (subsystem.isAutostart())
+ subsystem.start();
+ return subsystem;
+ }
+
+// private void setImportIsolationPolicy(AriesSubsystem subsystem) throws BundleException, IOException, InvalidSyntaxException, URISyntaxException {
+// if (subsystem.isRoot() || !subsystem.isScoped())
+// return;
+// Region region = subsystem.getRegion();
+// Region from = region;
+// RegionFilterBuilder builder = from.getRegionDigraph().createRegionFilterBuilder();
+// Region to = ((AriesSubsystem)subsystem.getParents().iterator().next()).getRegion();
+// addSubsystemServiceImportToSharingPolicy(builder, to, subsystem);
+// // TODO Is this check really necessary? Looks like it was done at the beginning of this method.
+// if (subsystem.isScoped()) {
+// // Both applications and composites have Import-Package headers that require processing.
+// // In the case of applications, the header is generated.
+// Header<?> header = subsystem.getSubsystemManifest().getImportPackageHeader();
+// setImportIsolationPolicy(builder, (ImportPackageHeader)header, subsystem);
+// // Both applications and composites have Require-Capability headers that require processing.
+// // In the case of applications, the header is generated.
+// header = subsystem.getSubsystemManifest().getRequireCapabilityHeader();
+// setImportIsolationPolicy(builder, (RequireCapabilityHeader)header, subsystem);
+// // Both applications and composites have Subsystem-ImportService headers that require processing.
+// // In the case of applications, the header is generated.
+// header = subsystem.getSubsystemManifest().getSubsystemImportServiceHeader();
+// setImportIsolationPolicy(builder, (SubsystemImportServiceHeader)header, subsystem);
+// header = subsystem.getSubsystemManifest().getRequireBundleHeader();
+// setImportIsolationPolicy(builder, (RequireBundleHeader)header, subsystem);
+// }
+// RegionFilter regionFilter = builder.build();
+// from.connectRegion(to, regionFilter);
+// }
+//
+// private void setImportIsolationPolicy(RegionFilterBuilder builder, ImportPackageHeader header, AriesSubsystem subsystem) throws InvalidSyntaxException {
+// if (header == null)
+// return;
+// String policy = RegionFilter.VISIBLE_PACKAGE_NAMESPACE;
+// for (ImportPackageHeader.Clause clause : header.getClauses()) {
+// ImportPackageRequirement requirement = new ImportPackageRequirement(clause, subsystem);
+// String filter = requirement.getDirectives().get(ImportPackageRequirement.DIRECTIVE_FILTER);
+// builder.allow(policy, filter);
+// }
+// }
+//
+// private void setImportIsolationPolicy(RegionFilterBuilder builder, RequireBundleHeader header, AriesSubsystem subsystem) throws InvalidSyntaxException {
+// if (header == null)
+// return;
+// for (RequireBundleHeader.Clause clause : header.getClauses()) {
+// RequireBundleRequirement requirement = new RequireBundleRequirement(clause, subsystem);
+// String policy = RegionFilter.VISIBLE_REQUIRE_NAMESPACE;
+// String filter = requirement.getDirectives().get(RequireBundleRequirement.DIRECTIVE_FILTER);
+// builder.allow(policy, filter);
+// }
+// }
+//
+// private void setImportIsolationPolicy(RegionFilterBuilder builder, RequireCapabilityHeader header, AriesSubsystem subsystem) throws InvalidSyntaxException {
+// if (header == null)
+// return;
+// for (RequireCapabilityHeader.Clause clause : header.getClauses()) {
+// RequireCapabilityRequirement requirement = new RequireCapabilityRequirement(clause, subsystem);
+// String policy = requirement.getNamespace();
+// String filter = requirement.getDirectives().get(RequireCapabilityRequirement.DIRECTIVE_FILTER);
+// builder.allow(policy, filter);
+// }
+// }
+//
+// private void setImportIsolationPolicy(RegionFilterBuilder builder, SubsystemImportServiceHeader header, AriesSubsystem subsystem) throws InvalidSyntaxException {
+// if (header == null)
+// return;
+// for (SubsystemImportServiceHeader.Clause clause : header.getClauses()) {
+// SubsystemImportServiceRequirement requirement = new SubsystemImportServiceRequirement(clause, subsystem);
+// String policy = RegionFilter.VISIBLE_SERVICE_NAMESPACE;
+// String filter = requirement.getDirectives().get(SubsystemImportServiceRequirement.DIRECTIVE_FILTER);
+// builder.allow(policy, filter);
+// }
+// }
}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceUninstaller.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceUninstaller.java?rev=1353319&r1=1353318&r2=1353319&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceUninstaller.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemResourceUninstaller.java Sun Jun 24 19:48:40 2012
@@ -25,6 +25,7 @@ public class SubsystemResourceUninstalle
removeReferences();
removeConstituents();
removeChildren();
+ removeSubsystem();
}
private void removeChildren() {
@@ -54,31 +55,39 @@ public class SubsystemResourceUninstalle
removeReference((AriesSubsystem)subsystem, (AriesSubsystem)resource);
}
+ private void removeSubsystem() {
+ Activator.getInstance().getSubsystems().removeSubsystem((AriesSubsystem)resource);
+ }
+
private void uninstallSubsystem() {
- AriesSubsystem subsystem = (AriesSubsystem)resource;
+ AriesSubsystem subsystem = (AriesSubsystem) resource;
if (subsystem.getState().equals(Subsystem.State.RESOLVED))
- subsystem.setState(State.INSTALLED);
- subsystem.setState(State.UNINSTALLING);
- Throwable firstError = null;
- for (Resource resource : Activator.getInstance().getSubsystems().getResourcesReferencedBy(subsystem)) {
- // Don't uninstall the region context bundle here.
- if (ResourceHelper.getSymbolicNameAttribute(resource).startsWith(RegionContextBundleHelper.SYMBOLICNAME_PREFIX))
- continue;
- try {
- ResourceUninstaller.newInstance(resource, subsystem).uninstall();
- }
- catch (Throwable t) {
- logger.error("An error occurred while uninstalling resource " + resource + " of subsystem " + subsystem, t);
- if (firstError == null)
- firstError = t;
- }
+ subsystem.setState(State.INSTALLED);
+ subsystem.setState(State.UNINSTALLING);
+ Throwable firstError = null;
+ for (Resource resource : Activator.getInstance().getSubsystems()
+ .getResourcesReferencedBy(subsystem)) {
+ // Don't uninstall the region context bundle here.
+ if (ResourceHelper.getSymbolicNameAttribute(resource).startsWith(
+ RegionContextBundleHelper.SYMBOLICNAME_PREFIX))
+ continue;
+ try {
+ ResourceUninstaller.newInstance(resource, subsystem)
+ .uninstall();
+ } catch (Throwable t) {
+ logger.error("An error occurred while uninstalling resource "
+ + resource + " of subsystem " + subsystem, t);
+ if (firstError == null)
+ firstError = t;
}
- IOUtils.deleteRecursive(subsystem.getDirectory());
- subsystem.setState(State.UNINSTALLED);
- Activator.getInstance().getSubsystemServiceRegistrar().unregister(subsystem);
- if (subsystem.isScoped())
- RegionContextBundleHelper.uninstallRegionContextBundle(subsystem);
- if (firstError != null)
- throw new SubsystemException(firstError);
+ }
+ subsystem.setState(State.UNINSTALLED);
+ Activator.getInstance().getSubsystemServiceRegistrar()
+ .unregister(subsystem);
+ if (subsystem.isScoped())
+ RegionContextBundleHelper.uninstallRegionContextBundle(subsystem);
+ if (firstError != null)
+ throw new SubsystemException(firstError);
+ IOUtils.deleteRecursive(subsystem.getDirectory());
}
}
\ No newline at end of file
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemServiceRegistrar.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemServiceRegistrar.java?rev=1353319&r1=1353318&r2=1353319&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemServiceRegistrar.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/SubsystemServiceRegistrar.java Sun Jun 24 19:48:40 2012
@@ -43,7 +43,7 @@ public class SubsystemServiceRegistrar {
public synchronized void register(AriesSubsystem child, AriesSubsystem parent) {
if (map.containsKey(child))
- throw new IllegalStateException("Subsystem '" + child + "' already has service registration '" + map.get(child) + "'");
+ return;
Dictionary<String, Object> properties = properties(child, parent);
ServiceRegistration<Subsystem> registration = context.registerService(Subsystem.class, child, properties);
map.put(child, registration);
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Subsystems.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Subsystems.java?rev=1353319&r1=1353318&r2=1353319&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Subsystems.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Subsystems.java Sun Jun 24 19:48:40 2012
@@ -1,31 +1,36 @@
package org.apache.aries.subsystem.core.internal;
+import java.io.File;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.wiring.BundleRevision;
import org.osgi.resource.Resource;
+import org.osgi.service.coordinator.Coordination;
import org.osgi.service.subsystem.Subsystem;
+import org.osgi.service.subsystem.SubsystemException;
public class Subsystems {
- private final SubsystemGraph graph;
+ private AriesSubsystem root;
+ private volatile SubsystemGraph graph;
+
private final Map<Long, AriesSubsystem> idToSubsystem = new HashMap<Long, AriesSubsystem>();
private final Map<String, AriesSubsystem> locationToSubsystem = new HashMap<String, AriesSubsystem>();
private final ResourceReferences resourceReferences = new ResourceReferences();
- private final AriesSubsystem root;
private final Map<AriesSubsystem, Set<Resource>> subsystemToConstituents = new HashMap<AriesSubsystem, Set<Resource>>();
- public Subsystems() throws Exception {
- root = new AriesSubsystem();
- graph = new SubsystemGraph(root);
- }
-
public void addChild(AriesSubsystem parent, AriesSubsystem child) {
graph.add(parent, child);
+ child.addedParent(parent);
}
public void addConstituent(AriesSubsystem subsystem, Resource constituent) {
@@ -35,9 +40,9 @@ public class Subsystems {
constituents = new HashSet<Resource>();
subsystemToConstituents.put(subsystem, constituents);
}
- if (!constituents.add(constituent))
- throw new IllegalArgumentException("Constituent already exists");
+ constituents.add(constituent);
}
+ subsystem.addedContent(constituent);
}
public void addReference(AriesSubsystem subsystem, Resource resource) {
@@ -62,7 +67,7 @@ public class Subsystems {
Collection<Resource> result = subsystemToConstituents.get(subsystem);
if (result == null)
return Collections.emptyList();
- return Collections.unmodifiableCollection(result);
+ return Collections.unmodifiableCollection(new ArrayList<Resource>(result));
}
}
@@ -74,7 +79,83 @@ public class Subsystems {
return resourceReferences.getResources(subsystem);
}
- public AriesSubsystem getRootSubsystem() {
+ public synchronized AriesSubsystem getRootSubsystem() {
+ if (root == null) {
+ File file = Activator.getInstance().getBundleContext().getDataFile("");
+ File[] fileArray = file.listFiles();
+ List<File> fileList = new ArrayList<File>(Arrays.asList(fileArray));
+ Collections.sort(fileList, new Comparator<File>() {
+ @Override
+ public int compare(File file1, File file2) {
+ String name1 = file1.getName();
+ String name2 = file2.getName();
+ return Long.valueOf(name1).compareTo(Long.valueOf(name2));
+ }
+ });
+ if (fileList.isEmpty()) {
+ SubsystemResource resource;
+ try {
+ resource = new SubsystemResource(file);
+ }
+ catch (SubsystemException e) {
+ throw e;
+ }
+ catch (Exception e) {
+ throw new SubsystemException(e);
+ }
+ Coordination coordination = Utils.createCoordination();
+ try {
+ root = (AriesSubsystem)ResourceInstaller.newInstance(coordination, resource, null, false).install();
+ // TODO Begin proof of concept.
+ // This is a proof of concept for initializing the relationships between the root subsystem and bundles
+ // that already existed in its region. Not sure this will be the final resting place. Plus, there are issues
+ // since this does not take into account the possibility of already existing bundles going away or new bundles
+ // being installed out of band while this initialization is taking place. Need a bundle event hook for that.
+ BundleContext context = Activator.getInstance().getBundleContext().getBundle(0).getBundleContext();
+ for (long id : root.getRegion().getBundleIds()) {
+ BundleRevision br = context.getBundle(id).adapt(BundleRevision.class);
+ ResourceInstaller.newInstance(coordination, br, root, false).install();
+ }
+ // TODO End proof of concept.
+ } catch (Exception e) {
+ coordination.fail(e);
+ } finally {
+ coordination.end();
+ }
+ // TODO This initialization is a bit brittle. The root subsystem
+ // must be gotten before anything else will be able to use the
+ // graph. At the very least, throw IllegalStateException where
+ // appropriate.
+ graph = new SubsystemGraph(root);
+ }
+ else {
+ Coordination coordination = Utils.createCoordination();
+ Collection<AriesSubsystem> subsystems = new ArrayList<AriesSubsystem>(fileList.size());
+ try {
+ for (File f : fileList) {
+ AriesSubsystem s = new AriesSubsystem(f);
+ subsystems.add(s);
+ addSubsystem(s);
+ }
+ root = getSubsystemById(0);
+ graph = new SubsystemGraph(root);
+ for (AriesSubsystem s : subsystems) {
+ Collection<Subsystem> parents = s.getParents();
+ if (parents == null || parents.isEmpty()) {
+ ResourceInstaller.newInstance(coordination, s, null, false).install();
+ }
+ else {
+ for (Subsystem parent : s.getParents())
+ ResourceInstaller.newInstance(coordination, s, (AriesSubsystem)parent, false).install();
+ }
+ }
+ } catch (Exception e) {
+ coordination.fail(e);
+ } finally {
+ coordination.end();
+ }
+ }
+ }
return root;
}
@@ -98,7 +179,7 @@ public class Subsystems {
ArrayList<AriesSubsystem> result = new ArrayList<AriesSubsystem>();
synchronized (subsystemToConstituents) {
for (AriesSubsystem subsystem : subsystemToConstituents.keySet())
- if (subsystem.contains(constituent))
+ if (getConstituents(subsystem).contains(constituent))
result.add(subsystem);
}
result.trimToSize();
@@ -120,9 +201,9 @@ public class Subsystems {
public void removeConstituent(AriesSubsystem subsystem, Resource constituent) {
synchronized (subsystemToConstituents) {
Set<Resource> constituents = subsystemToConstituents.get(subsystem);
- if (!constituents.remove(constituent))
- throw new IllegalArgumentException("Constituent does not exist");
+ constituents.remove(constituent);
}
+ subsystem.removedContent(constituent);
}
public void removeReference(AriesSubsystem subsystem, Resource resource) {
@@ -140,27 +221,21 @@ public class Subsystems {
private void addIdToSubsystem(AriesSubsystem subsystem) {
long id = subsystem.getSubsystemId();
- if (idToSubsystem.containsKey(id))
- throw new IllegalArgumentException("Subsystem ID already exists: " + id);
idToSubsystem.put(id, subsystem);
}
private void addLocationToSubsystem(AriesSubsystem subsystem) {
String location = subsystem.getLocation();
- if (locationToSubsystem.containsKey(location))
- throw new IllegalArgumentException("Subsystem location already exists: " + location);
locationToSubsystem.put(location, subsystem);
}
private void removeIdToSubsystem(AriesSubsystem subsystem) {
long id = subsystem.getSubsystemId();
- if (idToSubsystem.remove(id) == null)
- throw new IllegalArgumentException("Subsystem ID does not exist: " + id);
+ idToSubsystem.remove(id);
}
private void removeLocationToSubsystem(AriesSubsystem subsystem) {
String location = subsystem.getLocation();
- if (locationToSubsystem.remove(location) == null)
- throw new IllegalArgumentException("Subsystem location does not exist: " + location);
+ locationToSubsystem.remove(location);
}
}