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/02/08 14:54:44 UTC
svn commit: r1241900 [3/8] - in /aries/trunk/subsystem: ./ subsystem-api/
subsystem-api/src/main/java/org/osgi/service/repository/
subsystem-api/src/main/java/org/osgi/service/resolver/
subsystem-api/src/main/java/org/osgi/service/subsystem/ subsystem-...
Modified: aries/trunk/subsystem/subsystem-core/pom.xml
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/pom.xml?rev=1241900&r1=1241899&r2=1241900&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/pom.xml (original)
+++ aries/trunk/subsystem/subsystem-core/pom.xml Wed Feb 8 13:54:41 2012
@@ -44,12 +44,17 @@
org.apache.aries.subsystem.core.internal.Activator
</aries.osgi.activator>
<aries.osgi.private.pkg>
+ org.apache.aries.subsystem.core,
+ org.apache.aries.subsystem.core.archive,
org.apache.aries.subsystem.core.internal,
org.apache.aries.subsystem.core.obr,
- org.apache.felix.utils.manifest
+ org.apache.aries.subsystem.core.obr.felix,
+ org.apache.aries.subsystem.core.resource,
+ org.apache.felix.resolver,
+ org.apache.felix.resolver.impl
</aries.osgi.private.pkg>
<aries.osgi.import>
- *
+ *
</aries.osgi.import>
</properties>
@@ -68,7 +73,7 @@
<dependency>
<groupId>org.apache.aries</groupId>
<artifactId>org.apache.aries.util</artifactId>
- <version>0.4-SNAPSHOT</version>
+ <version>0.5-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.osgi</groupId>
@@ -87,32 +92,32 @@
</exclusion>
</exclusions>
</dependency>
+ <dependency>
+ <groupId>org.apache.aries.application</groupId>
+ <artifactId>org.apache.aries.application.utils</artifactId>
+ <version>0.3.1-SNAPSHOT</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
<dependency>
<groupId>org.eclipse</groupId>
- <artifactId>osgi</artifactId>
+ <artifactId>org.eclipse.osgi</artifactId>
<version>3.8.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.equinox</groupId>
- <artifactId>coordinator</artifactId>
- <version>1.0.0.v20110314</version>
+ <artifactId>org.eclipse.equinox.coordinator</artifactId>
+ <version>3.8.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.equinox</groupId>
- <artifactId>region</artifactId>
- <version>1.0.0.v20110506</version>
- </dependency>
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.utils</artifactId>
- <version>1.1.0</version>
- <exclusions>
- <exclusion>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- </exclusion>
- </exclusions>
+ <artifactId>org.eclipse.equinox.region</artifactId>
+ <version>3.8.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.felix</groupId>
@@ -128,7 +133,7 @@
<dependency>
<groupId>org.apache.aries.testsupport</groupId>
<artifactId>org.apache.aries.testsupport.unit</artifactId>
- <version>0.4-SNAPSHOT</version>
+ <version>0.5-SNAPSHOT</version>
<scope>test</scope>
<exclusions>
<exclusion>
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/ResourceHelper.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/ResourceHelper.java?rev=1241900&r1=1241899&r2=1241900&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/ResourceHelper.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/ResourceHelper.java Wed Feb 8 13:54:41 2012
@@ -13,17 +13,39 @@
*/
package org.apache.aries.subsystem.core;
+import static org.apache.aries.application.utils.AppConstants.LOG_ENTRY;
+import static org.apache.aries.application.utils.AppConstants.LOG_EXIT;
+
import java.util.Collection;
import java.util.List;
+import org.apache.aries.subsystem.core.archive.TypeAttribute;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.Version;
import org.osgi.framework.resource.Capability;
import org.osgi.framework.resource.Requirement;
import org.osgi.framework.resource.Resource;
import org.osgi.framework.resource.ResourceConstants;
import org.osgi.service.repository.Repository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class ResourceHelper {
+ private static final Logger logger = LoggerFactory.getLogger(ResourceHelper.class);
+
+ public static boolean areEqual(Resource resource1, Resource resource2) {
+ if (getTypeAttribute(resource1).equals(getTypeAttribute(resource2))) {
+ if (getSymbolicNameAttribute(resource1).equals(getSymbolicNameAttribute(resource2))) {
+ if (getVersionAttribute(resource1).equals(getVersionAttribute(resource2))) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
public static String getContentAttribute(Resource resource) {
// TODO Add to constants.
return (String)getContentAttribute(resource, "osgi.content");
@@ -52,10 +74,46 @@ public class ResourceHelper {
}
public static String getTypeAttribute(Resource resource) {
- return (String)getIdentityAttribute(resource, ResourceConstants.IDENTITY_TYPE_ATTRIBUTE);
+ String result = (String)getIdentityAttribute(resource, ResourceConstants.IDENTITY_TYPE_ATTRIBUTE);
+ if (result == null)
+ result = TypeAttribute.DEFAULT_VALUE;
+ return result;
}
public static Version getVersionAttribute(Resource resource) {
- return (Version)getIdentityAttribute(resource, ResourceConstants.IDENTITY_VERSION_ATTRIBUTE);
+ Version result = (Version)getIdentityAttribute(resource, ResourceConstants.IDENTITY_VERSION_ATTRIBUTE);
+ if (result == null)
+ result = Version.emptyVersion;
+ return result;
+ }
+
+ public static boolean matches(Requirement requirement, Capability capability) {
+ if (logger.isDebugEnabled())
+ logger.debug(LOG_ENTRY, "matches", new Object[]{requirement, capability});
+ boolean result = false;
+ if (requirement == null && capability == null)
+ result = true;
+ else if (requirement == null || capability == null)
+ result = false;
+ else if (!capability.getNamespace().equals(requirement.getNamespace()))
+ result = false;
+ else {
+ String filterStr = requirement.getDirectives().get(Constants.FILTER_DIRECTIVE);
+ if (filterStr == null)
+ result = true;
+ else {
+ try {
+ if (FrameworkUtil.createFilter(filterStr).matches(capability.getAttributes()))
+ result = true;
+ }
+ catch (InvalidSyntaxException e) {
+ logger.debug("Requirement had invalid filter string: " + requirement, e);
+ result = false;
+ }
+ }
+ }
+ // TODO Check directives.
+ logger.debug(LOG_EXIT, "matches", result);
+ return result;
}
}
Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleManifestVersionHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleManifestVersionHeader.java?rev=1241900&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleManifestVersionHeader.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleManifestVersionHeader.java Wed Feb 8 13:54:41 2012
@@ -0,0 +1,16 @@
+package org.apache.aries.subsystem.core.archive;
+
+import org.osgi.framework.Constants;
+
+public class BundleManifestVersionHeader extends VersionHeader {
+ public static final String DEFAULT_VALUE = "2.0";
+ public static final String NAME = Constants.BUNDLE_MANIFESTVERSION;
+
+ public BundleManifestVersionHeader() {
+ this(DEFAULT_VALUE);
+ }
+
+ public BundleManifestVersionHeader(String value) {
+ super(NAME, value);
+ }
+}
Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleSymbolicNameHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleSymbolicNameHeader.java?rev=1241900&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleSymbolicNameHeader.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleSymbolicNameHeader.java Wed Feb 8 13:54:41 2012
@@ -0,0 +1,11 @@
+package org.apache.aries.subsystem.core.archive;
+
+import org.osgi.framework.Constants;
+
+public class BundleSymbolicNameHeader extends SymbolicNameHeader {
+ public static final String NAME = Constants.BUNDLE_SYMBOLICNAME;
+
+ public BundleSymbolicNameHeader(String value) {
+ super(NAME, value);
+ }
+}
Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleVersionHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleVersionHeader.java?rev=1241900&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleVersionHeader.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/BundleVersionHeader.java Wed Feb 8 13:54:41 2012
@@ -0,0 +1,17 @@
+package org.apache.aries.subsystem.core.archive;
+
+import org.osgi.framework.Constants;
+import org.osgi.framework.Version;
+
+public class BundleVersionHeader extends VersionHeader {
+ public static final String DEFAULT_VALUE = Version.emptyVersion.toString();
+ public static final String NAME = Constants.BUNDLE_VERSION;
+
+ public BundleVersionHeader() {
+ this(DEFAULT_VALUE);
+ }
+
+ public BundleVersionHeader(String value) {
+ super(NAME, value);
+ }
+}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/DeploymentManifest.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/DeploymentManifest.java?rev=1241900&r1=1241899&r2=1241900&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/DeploymentManifest.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/DeploymentManifest.java Wed Feb 8 13:54:41 2012
@@ -13,51 +13,73 @@
*/
package org.apache.aries.subsystem.core.archive;
+import static org.apache.aries.application.utils.AppConstants.LOG_ENTRY;
+import static org.apache.aries.application.utils.AppConstants.LOG_EXIT;
+
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import org.apache.aries.subsystem.core.internal.Activator;
+import org.apache.aries.subsystem.core.internal.OsgiIdentityCapability;
import org.apache.aries.subsystem.core.internal.OsgiIdentityRequirement;
import org.apache.aries.subsystem.core.obr.SubsystemEnvironment;
+import org.osgi.framework.Version;
+import org.osgi.framework.resource.Capability;
+import org.osgi.framework.resource.Requirement;
import org.osgi.framework.resource.Resource;
+import org.osgi.framework.resource.ResourceConstants;
import org.osgi.framework.resource.Wire;
+import org.osgi.service.resolver.Resolver;
import org.osgi.service.subsystem.SubsystemException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-public class DeploymentManifest extends Manifest {
- public static DeploymentManifest newInstance(Archive archive, SubsystemEnvironment environment) {
- SubsystemManifest manifest = archive.getSubsystemManifest();
+public class DeploymentManifest extends Manifest implements Resource {
+ public static final String IDENTITY_TYPE = "org.apache.aries.subsystem.manifest.deployment";
+
+ private static final Logger logger = LoggerFactory.getLogger(DeploymentManifest.class);
+
+ public static DeploymentManifest newInstance(SubsystemManifest manifest, SubsystemEnvironment environment) {
+ if (logger.isDebugEnabled())
+ logger.debug(LOG_ENTRY, "newInstance", new Object[]{manifest, environment});
DeploymentManifest result = new DeploymentManifest();
result.headers.put(ManifestVersionHeader.NAME, manifest.getManifestVersion());
- Collection<Resource> resources = new ArrayList<Resource>();
- for (SubsystemContentHeader.Content content : manifest.getSubsystemContent().getContents()) {
- OsgiIdentityRequirement requirement = new OsgiIdentityRequirement(content.getName(), content.getVersionRange(), content.getType(), false);
- Resource resource = environment.findResource(requirement);
- // If the resource is null, can't continue.
- // TODO Actually, can continue if resource is optional.
- if (resource == null)
- throw new SubsystemException("Resource does not exist: " + resource);
- resources.add(resource);
- }
- // TODO This does not validate that all content bundles were found.
- Map<Resource, List<Wire>> resolution = Activator.getResolver().resolve(environment, resources, Collections.EMPTY_LIST);
- // TODO Once we have a resolver that actually returns lists of wires, we can use them to compute other manifest headers such as Import-Package.
- Collection<Resource> deployedContent = new ArrayList<Resource>();
- Collection<Resource> provisionResource = new ArrayList<Resource>();
- for (Resource resource : resolution.keySet()) {
- if (environment.isContentResource(resource))
- deployedContent.add(resource);
- else
- provisionResource.add(resource);
+ Collection<Resource> resources = new HashSet<Resource>();
+ SubsystemContentHeader contentHeader = manifest.getSubsystemContent();
+ if (contentHeader != null) {
+ for (SubsystemContentHeader.Content content : contentHeader.getContents()) {
+ OsgiIdentityRequirement requirement = new OsgiIdentityRequirement(content.getName(), content.getVersionRange(), content.getType(), false);
+ Resource resource = environment.findResource(requirement);
+ // If the resource is null, can't continue.
+ // TODO Actually, can continue if resource is optional.
+ if (resource == null)
+ throw new SubsystemException("Resource does not exist: " + requirement);
+ resources.add(resource);
+ }
+ // TODO This does not validate that all content bundles were found.
+ Map<Resource, List<Wire>> resolution = Activator.getInstance().getServiceProvider().getService(Resolver.class).resolve(environment, resources, Collections.EMPTY_LIST);
+ // TODO Once we have a resolver that actually returns lists of wires, we can use them to compute other manifest headers such as Import-Package.
+ Collection<Resource> deployedContent = new HashSet<Resource>();
+ Collection<Resource> provisionResource = new HashSet<Resource>();
+ for (Resource resource : resolution.keySet()) {
+ if (contentHeader.contains(resource))
+ deployedContent.add(resource);
+ else
+ provisionResource.add(resource);
+ }
+ // Make sure any already resolved content resources are added back in.
+ deployedContent.addAll(resources);
+ result.headers.put(DeployedContentHeader.NAME, DeployedContentHeader.newInstance(deployedContent));
+ if (!provisionResource.isEmpty())
+ result.headers.put(ProvisionResourceHeader.NAME, ProvisionResourceHeader.newInstance(provisionResource));
}
- result.headers.put(DeployedContentHeader.NAME, DeployedContentHeader.newInstance(deployedContent));
- if (!provisionResource.isEmpty())
- result.headers.put(ProvisionResourceHeader.NAME, ProvisionResourceHeader.newInstance(provisionResource));
result.headers.put(SubsystemSymbolicNameHeader.NAME, manifest.getSubsystemSymbolicName());
result.headers.put(SubsystemVersionHeader.NAME, manifest.getSubsystemVersion());
SubsystemTypeHeader typeHeader = manifest.getSubsystemType();
@@ -71,6 +93,7 @@ public class DeploymentManifest extends
// TODO Compute additional headers for a composite.
}
// Features require no additional headers.
+ logger.debug(LOG_EXIT, "newInstance", result);
return result;
}
@@ -91,6 +114,26 @@ public class DeploymentManifest extends
headers.put(ProvisionResourceHeader.NAME, ProvisionResourceHeader.newInstance(provisionResource));
}
+ @Override
+ public List<Capability> getCapabilities(String namespace) {
+ List<Capability> result = new ArrayList<Capability>(1);
+ if (namespace == null || namespace.equals(ResourceConstants.IDENTITY_NAMESPACE)) {
+ OsgiIdentityCapability capability = new OsgiIdentityCapability(
+ this,
+ // TODO Reusing IDENTITY_TYPE for the symbolic name here.
+ // Since there's only one subsystem manifest per subsystem,
+ // this shouldn't cause any technical issues. However, it
+ // might be best to use the subsystem's symbolic name here.
+ // But there are issues with that as well since type is not
+ // part of the unique identity.
+ IDENTITY_TYPE,
+ Version.emptyVersion,
+ IDENTITY_TYPE);
+ result.add(capability);
+ }
+ return result;
+ }
+
public DeployedContentHeader getDeployedContent() {
return (DeployedContentHeader)getHeader(DeployedContentHeader.NAME);
}
@@ -98,4 +141,20 @@ public class DeploymentManifest extends
public ProvisionResourceHeader getProvisionResource() {
return (ProvisionResourceHeader)getHeader(ProvisionResourceHeader.NAME);
}
+
+ @Override
+ public List<Requirement> getRequirements(String namespace) {
+ return Collections.emptyList();
+ }
+
+ public SubsystemSymbolicNameHeader getSubsystemSymbolicName() {
+ return (SubsystemSymbolicNameHeader)getHeader(SubsystemSymbolicNameHeader.NAME);
+ }
+
+ public SubsystemVersionHeader getSubsystemVersion() {
+ SubsystemVersionHeader result = (SubsystemVersionHeader)getHeader(SubsystemVersionHeader.NAME);
+ if (result == null)
+ return SubsystemVersionHeader.DEFAULT;
+ return result;
+ }
}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ExportPackageHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ExportPackageHeader.java?rev=1241900&r1=1241899&r2=1241900&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ExportPackageHeader.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/ExportPackageHeader.java Wed Feb 8 13:54:41 2012
@@ -19,6 +19,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.apache.aries.subsystem.core.resource.AbstractCapability;
import org.osgi.framework.Constants;
import org.osgi.framework.Version;
import org.osgi.framework.resource.Capability;
@@ -37,7 +38,7 @@ public class ExportPackageHeader extends
for (final Clause clause : clauses) {
String[] exportedPackages = clause.getPath().split(";");
for (final String exportedPackage : exportedPackages) {
- capabilities.add(new Capability() {
+ capabilities.add(new AbstractCapability() {
@Override
public String getNamespace() {
return ResourceConstants.WIRING_PACKAGE_NAMESPACE;
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/GenericClause.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/GenericClause.java?rev=1241900&r1=1241899&r2=1241900&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/GenericClause.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/GenericClause.java Wed Feb 8 13:54:41 2012
@@ -22,7 +22,10 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class GenericClause implements Clause {
- private static final String REGEX = '(' + Grammar.PATH + "(?:;" + Grammar.PATH + ")*)(?:;(" + Grammar.PARAMETER + "))*";
+ // TODO The introduction of the whitespace (\\s*) before a parameter was added to get around a grammatically
+ // incorrect clause in Equinox: org.eclipse.osgi; singleton:=true;deployed-version=3.7.0.v20110221;type=osgi.bundle.
+ // Note the space before the singleton directive.
+ private static final String REGEX = '(' + Grammar.PATH + "(?:;" + Grammar.PATH + ")*)(?:;\\s*(" + Grammar.PARAMETER + "))*";
private static final Pattern PATTERN = Pattern.compile(REGEX);
private static final Pattern PATTERN_PARAMETER = Pattern.compile(Grammar.PARAMETER);
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/Grammar.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/Grammar.java?rev=1241900&r1=1241899&r2=1241900&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/Grammar.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/Grammar.java Wed Feb 8 13:54:41 2012
@@ -89,7 +89,10 @@ public interface Grammar {
public static final String PATH_UNQUOTED = PATH_SEP + '|' + PATH_SEP + '?' + PATH_ELEMENT + "(?:" + PATH_SEP + PATH_ELEMENT + ")*";
public static final String PATH_UNQUOTED_NT = PATH_SEP + '|' + PATH_SEP + '?' + PATH_ELEMENT_NT + "(?:" + PATH_SEP + PATH_ELEMENT_NT + ")*";
public static final String PATH = "(?:" + PATH_UNQUOTED_NT + ")|\"(?:" + PATH_UNQUOTED + ")\"";
- public static final String CLAUSE = "(?:" + PATH + ")(?:;" + PATH + ")*(?:;(?:" + PARAMETER + "))*";
+ // TODO The introduction of the whitespace (\\s*) before a parameter was added to get around a grammatically
+ // incorrect clause in Equinox: org.eclipse.osgi; singleton:=true;deployed-version=3.7.0.v20110221;type=osgi.bundle.
+ // Note the space before the singleton directive.
+ public static final String CLAUSE = "(?:" + PATH + ")(?:;" + PATH + ")*(?:;\\s*(?:" + PARAMETER + "))*";
public static final String HEADERCHAR = ALPHANUM + "|_|-";
public static final String NAME = ALPHANUM + "(?:" + HEADERCHAR + ")*";
public static final String HEADER = NAME + ": " + CLAUSE + "(?:," + CLAUSE + ")*";
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/HeaderFactory.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/HeaderFactory.java?rev=1241900&r1=1241899&r2=1241900&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/HeaderFactory.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/HeaderFactory.java Wed Feb 8 13:54:41 2012
@@ -90,6 +90,10 @@ public class HeaderFactory {
return new ExportPackageHeader(value);
if (ImportPackageHeader.NAME.equals(name))
return new ImportPackageHeader(value);
+ if (DeployedContentHeader.NAME.equals(name))
+ return new DeployedContentHeader(value);
+ if (ProvisionResourceHeader.NAME.equals(name))
+ return new ProvisionResourceHeader(value);
return new GenericHeader(name, value);
}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/Manifest.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/Manifest.java?rev=1241900&r1=1241899&r2=1241900&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/Manifest.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/Manifest.java Wed Feb 8 13:54:41 2012
@@ -27,7 +27,7 @@ import java.util.jar.Attributes;
import org.apache.aries.util.manifest.ManifestProcessor;
public abstract class Manifest {
- protected final Map<String, Header> headers = new HashMap<String, Header>();
+ protected final Map<String, Header> headers = Collections.synchronizedMap(new HashMap<String, Header>());
protected final java.util.jar.Manifest manifest;
public Manifest(InputStream in) throws IOException {
@@ -64,6 +64,19 @@ public abstract class Manifest {
return getHeader(Attributes.Name.MANIFEST_VERSION.toString());
}
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append('[').append(getClass().getName()).append(": ");
+ if (!headers.values().isEmpty()) {
+ for (Header header : headers.values())
+ sb.append(header.getName()).append('=').append(header.getValue()).append(", ");
+ sb.delete(sb.length() - 2, sb.length());
+ }
+ sb.append(']');
+ return sb.toString();
+ }
+
public void write(OutputStream out) throws IOException {
java.util.jar.Manifest m = new java.util.jar.Manifest();
Attributes attributes = m.getMainAttributes();
Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemArchive.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemArchive.java?rev=1241900&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemArchive.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemArchive.java Wed Feb 8 13:54:41 2012
@@ -0,0 +1,426 @@
+package org.apache.aries.subsystem.core.archive;
+
+import static org.apache.aries.application.utils.AppConstants.LOG_ENTRY;
+import static org.apache.aries.application.utils.AppConstants.LOG_EXIT;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import org.apache.aries.subsystem.core.ResourceHelper;
+import org.apache.aries.subsystem.core.internal.DataFile;
+import org.apache.aries.subsystem.core.internal.OsgiIdentityCapability;
+import org.apache.aries.subsystem.core.internal.StaticDataFile;
+import org.apache.aries.subsystem.core.resource.AbstractRequirement;
+import org.apache.aries.subsystem.core.resource.BundleResource;
+import org.apache.aries.subsystem.core.resource.SubsystemFileResource;
+import org.osgi.framework.Constants;
+import org.osgi.framework.resource.Capability;
+import org.osgi.framework.resource.Requirement;
+import org.osgi.framework.resource.Resource;
+import org.osgi.framework.resource.ResourceConstants;
+import org.osgi.service.repository.Repository;
+import org.osgi.service.repository.RepositoryContent;
+import org.osgi.service.subsystem.SubsystemConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SubsystemArchive implements Repository, RepositoryContent, Resource {
+ private static final Logger logger = LoggerFactory.getLogger(SubsystemArchive.class);
+
+ private final File directory;
+ private final Map<Resource, URL> resources = new HashMap<Resource, URL>();
+
+ public SubsystemArchive(File content) throws Exception {
+ logger.debug(LOG_ENTRY, "init", content);
+ if (!content.exists())
+ throw new IllegalArgumentException(content.getName());
+ if (content.isDirectory()) {
+ directory = content;
+ processDirectory(content);
+ }
+ else { // It's a file.
+ directory = content.getParentFile();
+ processFile(content);
+ }
+ logger.debug(LOG_EXIT, "init");
+ }
+
+ @Override
+ public synchronized Collection<Capability> findProviders(Requirement requirement) {
+ logger.debug(LOG_ENTRY, "findProviders", requirement);
+ Collection<Capability> capabilities = new ArrayList<Capability>(1);
+ for (Resource resource : resources.keySet()) {
+ logger.debug("Evaluating resource: " + resource);
+ for (Capability capability : resource.getCapabilities(requirement.getNamespace())) {
+ logger.debug("Evaluating capability: " + capability);
+ if (ResourceHelper.matches(requirement, capability)) {
+ logger.debug("Adding capability: " + capability);
+ capabilities.add(capability);
+ }
+ }
+ }
+ logger.debug(LOG_EXIT, "findProviders", capabilities);
+ return capabilities;
+ }
+
+ @Override
+ public Map<Requirement, Collection<Capability>> findProviders(Collection<? extends Requirement> requirements) {
+ Map<Requirement, Collection<Capability>> result = new HashMap<Requirement, Collection<Capability>>(requirements.size());
+ for (Requirement requirement : requirements)
+ result.put(requirement, findProviders(requirement));
+ return result;
+ }
+
+ @Override
+ public List<Capability> getCapabilities(String namespace) {
+ if (namespace == null || namespace.equals(ResourceConstants.IDENTITY_NAMESPACE)) {
+ List<Capability> result = new ArrayList<Capability>(1);
+ OsgiIdentityCapability capability = new OsgiIdentityCapability(
+ this,
+ getSubsystemManifest().getSubsystemSymbolicName().getSymbolicName(),
+ getSubsystemManifest().getSubsystemVersion().getVersion(),
+ SubsystemConstants.IDENTITY_TYPE_SUBSYSTEM);
+ result.add(capability);
+ return result;
+ }
+ return Collections.emptyList();
+ }
+
+ @Override
+ public synchronized InputStream getContent() throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ZipOutputStream zos = new ZipOutputStream(baos);
+ for (Resource resource : getResources()) {
+ ZipEntry ze = new ZipEntry(
+ new StringBuilder(ResourceHelper.getSymbolicNameAttribute(resource))
+ .append(';')
+ .append(ResourceHelper.getVersionAttribute(resource))
+ .append(';')
+ .append(ResourceHelper.getTypeAttribute(resource))
+ .toString());
+ try {
+ zos.putNextEntry(ze);
+ InputStream is = ((RepositoryContent) resource).getContent();
+ byte[] bytes = new byte[2048];
+ int read;
+ while ((read = is.read(bytes)) != -1)
+ zos.write(bytes, 0, read);
+ zos.closeEntry();
+ }
+ finally {
+ try {
+ zos.close();
+ }
+ catch (IOException e) {
+ logger.debug("Unable to close the stream: ", e);
+ }
+ }
+ }
+ return new ByteArrayInputStream(baos.toByteArray());
+ }
+
+ public synchronized DataFile getDataFile() {
+ Collection<Capability> capabilities = findProviders(new AbstractRequirement() {
+ @Override
+ public Map<String, Object> getAttributes() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public Map<String, String> getDirectives() {
+ Map<String, String> directives = new HashMap<String, String>(1);
+ directives.put(
+ Constants.FILTER_DIRECTIVE,
+ new StringBuilder()
+ .append('(')
+ .append(ResourceConstants.IDENTITY_TYPE_ATTRIBUTE)
+ .append('=')
+ .append(DataFile.IDENTITY_TYPE)
+ .append(')')
+ .toString());
+ return Collections.unmodifiableMap(directives);
+ }
+
+ @Override
+ public String getNamespace() {
+ return ResourceConstants.IDENTITY_NAMESPACE;
+ }
+
+ @Override
+ public Resource getResource() {
+ return null;
+ }
+ });
+ if (capabilities.isEmpty())
+ return null;
+ return (DataFile)capabilities.iterator().next().getResource();
+ }
+
+ public synchronized DeploymentManifest getDeploymentManifest() {
+ Collection<Capability> capabilities = findProviders(new AbstractRequirement() {
+ @Override
+ public Map<String, Object> getAttributes() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public Map<String, String> getDirectives() {
+ Map<String, String> directives = new HashMap<String, String>(1);
+ directives.put(
+ Constants.FILTER_DIRECTIVE,
+ new StringBuilder()
+ .append('(')
+ .append(ResourceConstants.IDENTITY_TYPE_ATTRIBUTE)
+ .append('=')
+ .append(DeploymentManifest.IDENTITY_TYPE)
+ .append(')')
+ .toString());
+ return Collections.unmodifiableMap(directives);
+ }
+
+ @Override
+ public String getNamespace() {
+ return ResourceConstants.IDENTITY_NAMESPACE;
+ }
+
+ @Override
+ public Resource getResource() {
+ return null;
+ }
+ });
+ if (capabilities.isEmpty())
+ return null;
+ return (DeploymentManifest)capabilities.iterator().next().getResource();
+ }
+
+ @Override
+ public List<Requirement> getRequirements(String namespace) {
+ return Collections.emptyList();
+ }
+
+ public synchronized Collection<Resource> getResources() {
+ Collection<Capability> capabilities = findProviders(new AbstractRequirement() {
+ @Override
+ public Map<String, Object> getAttributes() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public Map<String, String> getDirectives() {
+ Map<String, String> directives = new HashMap<String, String>(1);
+ directives.put(
+ Constants.FILTER_DIRECTIVE,
+ new StringBuilder("(")
+ .append(ResourceConstants.IDENTITY_TYPE_ATTRIBUTE)
+ .append("=osgi.*)")
+ .toString());
+ return Collections.unmodifiableMap(directives);
+ }
+
+ @Override
+ public String getNamespace() {
+ return ResourceConstants.IDENTITY_NAMESPACE;
+ }
+
+ @Override
+ public Resource getResource() {
+ return null;
+ }
+ });
+ if (capabilities.isEmpty())
+ return Collections.emptyList();
+ Collection<Resource> resources = new HashSet<Resource>(capabilities.size());
+ for (Capability capability : capabilities) {
+ resources.add(capability.getResource());
+ }
+ return resources;
+ }
+
+ public synchronized StaticDataFile getStaticDataFile() {
+ Collection<Capability> capabilities = findProviders(new AbstractRequirement() {
+ @Override
+ public Map<String, Object> getAttributes() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public Map<String, String> getDirectives() {
+ Map<String, String> directives = new HashMap<String, String>(1);
+ directives.put(
+ Constants.FILTER_DIRECTIVE,
+ new StringBuilder()
+ .append('(')
+ .append(ResourceConstants.IDENTITY_TYPE_ATTRIBUTE)
+ .append('=')
+ .append(StaticDataFile.IDENTITY_TYPE)
+ .append(')')
+ .toString());
+ return Collections.unmodifiableMap(directives);
+ }
+
+ @Override
+ public String getNamespace() {
+ return ResourceConstants.IDENTITY_NAMESPACE;
+ }
+
+ @Override
+ public Resource getResource() {
+ return null;
+ }
+ });
+ if (capabilities.isEmpty())
+ return null;
+ return (StaticDataFile)capabilities.iterator().next().getResource();
+ }
+
+ public synchronized SubsystemManifest getSubsystemManifest() {
+ logger.debug(LOG_ENTRY, "getSubsystemManifest");
+ Collection<Capability> capabilities = findProviders(new AbstractRequirement() {
+ @Override
+ public Map<String, Object> getAttributes() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public Map<String, String> getDirectives() {
+ Map<String, String> directives = new HashMap<String, String>(1);
+ directives.put(
+ Constants.FILTER_DIRECTIVE,
+ new StringBuilder()
+ .append('(')
+ .append(ResourceConstants.IDENTITY_TYPE_ATTRIBUTE)
+ .append('=')
+ .append(SubsystemManifest.IDENTITY_TYPE)
+ .append(')')
+ .toString());
+ return Collections.unmodifiableMap(directives);
+ }
+
+ @Override
+ public String getNamespace() {
+ return ResourceConstants.IDENTITY_NAMESPACE;
+ }
+
+ @Override
+ public Resource getResource() {
+ return null;
+ }
+ });
+ SubsystemManifest result = null;
+ if (!capabilities.isEmpty())
+ result = (SubsystemManifest)capabilities.iterator().next().getResource();
+ logger.debug(LOG_EXIT, "getSubsystemManifest", result);
+ return result;
+ }
+
+ public synchronized void setDataFile(DataFile dataFile) throws IOException {
+ DataFile old = getDataFile();
+ // TODO Add to constants.
+ File file = new File(directory, DataFile.IDENTITY_TYPE);
+ OutputStream out = new FileOutputStream(file);
+ try {
+ dataFile.write(out);
+ resources.remove(old);
+ resources.put(dataFile, file.toURI().toURL());
+ } finally {
+ out.close();
+ }
+ }
+
+ public synchronized void setDeploymentManifest(DeploymentManifest manifest) throws IOException {
+ logger.debug(LOG_ENTRY, "setDeploymentManifest", manifest);
+ DeploymentManifest old = getDeploymentManifest();
+ // TODO Add to constants.
+ File file = new File(directory, "OSGI-INF");
+ if (!file.exists() && !file.mkdir())
+ throw new IOException("Unable to make directory for "
+ + file.getCanonicalPath());
+ file = new File(file, "DEPLOYMENT.MF");
+ OutputStream out = new FileOutputStream(file);
+ try {
+ manifest.write(out);
+ resources.remove(old);
+ resources.put(manifest, file.toURI().toURL());
+ } finally {
+ out.close();
+ }
+ logger.debug(LOG_EXIT, "setDeploymentManifest");
+ }
+
+ public synchronized void setSubsystemManifest(SubsystemManifest manifest) throws IOException {
+ logger.debug(LOG_ENTRY, "setSubsystemManifest", manifest);
+ SubsystemManifest old = getSubsystemManifest();
+ // TODO Add to constants.
+ File file = new File(directory, "OSGI-INF");
+ if (!file.exists() && !file.mkdir())
+ throw new IOException("Unable to make directory for " + file.getCanonicalPath());
+ file = new File(file, "SUBSYSTEM.MF");
+ OutputStream out = new FileOutputStream(file);
+ try {
+ manifest.write(out);
+ resources.remove(old);
+ resources.put(manifest, file.toURI().toURL());
+ }
+ finally {
+ out.close();
+ }
+ logger.debug(LOG_EXIT, "setSubsystemManifest");
+ }
+
+ private Resource createResource(File file) throws Exception {
+ if (file.isDirectory() && file.getName().startsWith("subsystem"))
+ return new SubsystemArchive(file);
+ if (file.getName().endsWith(".jar"))
+ return BundleResource.newInstance(file.toURI().toURL());
+ else if (!file.getName().startsWith("subsystem") && file.getName().endsWith(".ssa"))
+ return new SubsystemFileResource(file);
+ else if (file.getName().endsWith("SUBSYSTEM.MF"))
+ return new SubsystemManifest(file);
+ else if (file.getName().endsWith("DEPLOYMENT.MF"))
+ return new DeploymentManifest(file);
+ else if (file.getName().endsWith(DataFile.IDENTITY_TYPE))
+ return new DataFile(file);
+ else if (file.getName().endsWith(StaticDataFile.IDENTITY_TYPE))
+ return new StaticDataFile(file);
+ logger.warn("Ignoring unsupported resource type: " + file.getCanonicalPath());
+ return null;
+ }
+
+ private void processDirectory(File content) throws Exception {
+ logger.debug(LOG_ENTRY, "processDirectory", content);
+ for (File file : content.listFiles()) {
+ logger.debug("Processing file {}", file);
+ processFile(file);
+ }
+ logger.debug(LOG_EXIT, "processDirectory");
+ }
+
+ private void processFile(File content) throws Exception {
+ logger.debug(LOG_ENTRY, "processFile", content);
+ if (content.isDirectory() && "OSGI-INF".equals(content.getName())) {
+ processDirectory(content);
+ }
+ else {
+ Resource resource = createResource(content);
+ if (resource != null) {
+ resources.put(resource, content.toURI().toURL());
+ }
+ }
+ logger.debug(LOG_EXIT, "processFile");
+ }
+}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemContentHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemContentHeader.java?rev=1241900&r1=1241899&r2=1241900&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemContentHeader.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemContentHeader.java Wed Feb 8 13:54:41 2012
@@ -19,9 +19,11 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
+import org.apache.aries.subsystem.core.ResourceHelper;
import org.apache.aries.util.VersionRange;
import org.osgi.framework.Constants;
import org.osgi.framework.Version;
+import org.osgi.framework.resource.Resource;
public class SubsystemContentHeader extends AbstractHeader {
public static class Content {
@@ -118,6 +120,19 @@ public class SubsystemContentHeader exte
}
});
}
+
+ public boolean contains(Resource resource) {
+ String symbolicName = ResourceHelper.getSymbolicNameAttribute(resource);
+ Version version = ResourceHelper.getVersionAttribute(resource);
+ String type = ResourceHelper.getTypeAttribute(resource);
+ for (Content content : contents) {
+ if (symbolicName.equals(content.getName())
+ && content.getVersionRange().matches(version)
+ && type.equals(content.getType()))
+ return true;
+ }
+ return false;
+ }
public Collection<Content> getContents() {
return Collections.unmodifiableCollection(contents);
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemManifest.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemManifest.java?rev=1241900&r1=1241899&r2=1241900&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemManifest.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemManifest.java Wed Feb 8 13:54:41 2012
@@ -13,21 +13,34 @@
*/
package org.apache.aries.subsystem.core.archive;
+import static org.apache.aries.application.utils.AppConstants.LOG_ENTRY;
+import static org.apache.aries.application.utils.AppConstants.LOG_EXIT;
+
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import org.apache.aries.subsystem.core.internal.OsgiIdentityCapability;
import org.osgi.framework.Version;
import org.osgi.framework.resource.Capability;
+import org.osgi.framework.resource.Requirement;
import org.osgi.framework.resource.Resource;
import org.osgi.framework.resource.ResourceConstants;
-import org.osgi.service.subsystem.SubsystemException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-public class SubsystemManifest extends Manifest {
+public class SubsystemManifest extends Manifest implements Resource {
+ public static final String IDENTITY_TYPE = "org.apache.aries.subsystem.manifest";
+
+ private static final Logger logger = LoggerFactory.getLogger(SubsystemManifest.class);
+
public static SubsystemManifest newInstance(String symbolicName, Version version, Collection<Resource> resources) {
- if (resources.isEmpty())
- throw new SubsystemException("A subsystem must have content");
+ if (logger.isDebugEnabled())
+ logger.debug(LOG_ENTRY, "newInstance", new Object[]{symbolicName, version, resources});
SubsystemManifest manifest = new SubsystemManifest();
manifest.headers.put(SubsystemTypeHeader.NAME, new SubsystemTypeHeader());
manifest.headers.put(ManifestVersionHeader.NAME, new ManifestVersionHeader());
@@ -49,9 +62,12 @@ public class SubsystemManifest extends M
// TODO Add to constants.
.append("type").append('=').append(type).append(',');
}
- // Remove the trailing comma.
- content.deleteCharAt(content.length() - 1);
- manifest.headers.put(SubsystemContentHeader.NAME, new SubsystemContentHeader(content.toString()));
+ if (content.length() != 0) {
+ // Remove the trailing comma.
+ content.deleteCharAt(content.length() - 1);
+ manifest.headers.put(SubsystemContentHeader.NAME, new SubsystemContentHeader(content.toString()));
+ }
+ logger.debug(LOG_EXIT, "newInstance", manifest);
return manifest;
}
@@ -65,6 +81,31 @@ public class SubsystemManifest extends M
private SubsystemManifest() {}
+ @Override
+ public List<Capability> getCapabilities(String namespace) {
+ List<Capability> result = new ArrayList<Capability>(1);
+ if (namespace == null || namespace.equals(ResourceConstants.IDENTITY_NAMESPACE)) {
+ OsgiIdentityCapability capability = new OsgiIdentityCapability(
+ this,
+ // TODO Reusing IDENTITY_TYPE for the symbolic name here.
+ // Since there's only one subsystem manifest per subsystem,
+ // this shouldn't cause any technical issues. However, it
+ // might be best to use the subsystem's symbolic name here.
+ // But there are issues with that as well since type is not
+ // part of the unique identity.
+ IDENTITY_TYPE,
+ Version.emptyVersion,
+ IDENTITY_TYPE);
+ result.add(capability);
+ }
+ return result;
+ }
+
+ @Override
+ public List<Requirement> getRequirements(String namespace) {
+ return Collections.emptyList();
+ }
+
public SubsystemContentHeader getSubsystemContent() {
return (SubsystemContentHeader)getHeader(SubsystemContentHeader.NAME);
}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemManifestVersionHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemManifestVersionHeader.java?rev=1241900&r1=1241899&r2=1241900&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemManifestVersionHeader.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemManifestVersionHeader.java Wed Feb 8 13:54:41 2012
@@ -13,10 +13,11 @@
*/
package org.apache.aries.subsystem.core.archive;
+import org.osgi.service.subsystem.SubsystemConstants;
+
public class SubsystemManifestVersionHeader extends VersionHeader {
public static final String DEFAULT_VALUE = "1.0";
- // TODO Add to constants.
- public static final String NAME = "Subsystem-ManifestVersion";
+ public static final String NAME = SubsystemConstants.SUBSYSTEM_MANIFESTVERSION;
public SubsystemManifestVersionHeader() {
this(DEFAULT_VALUE);
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemSymbolicNameHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemSymbolicNameHeader.java?rev=1241900&r1=1241899&r2=1241900&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemSymbolicNameHeader.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SubsystemSymbolicNameHeader.java Wed Feb 8 13:54:41 2012
@@ -13,21 +13,11 @@
*/
package org.apache.aries.subsystem.core.archive;
-import java.util.regex.Pattern;
-
-public class SubsystemSymbolicNameHeader extends AbstractHeader {
+public class SubsystemSymbolicNameHeader extends SymbolicNameHeader {
// TODO Add to constants.
public static final String NAME = "Subsystem-SymbolicName";
public SubsystemSymbolicNameHeader(String value) {
super(NAME, value);
- if (getClauses().size() != 1)
- throw new IllegalArgumentException(/* TODO Message */);
- if (!Pattern.matches(Grammar.SYMBOLICNAME, getClauses().get(0).getPath()))
- throw new IllegalArgumentException(/* TODO Message */);
- }
-
- public String getSymbolicName() {
- return getClauses().get(0).getPath();
}
}
Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SymbolicNameHeader.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SymbolicNameHeader.java?rev=1241900&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SymbolicNameHeader.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/archive/SymbolicNameHeader.java Wed Feb 8 13:54:41 2012
@@ -0,0 +1,17 @@
+package org.apache.aries.subsystem.core.archive;
+
+import java.util.regex.Pattern;
+
+public abstract class SymbolicNameHeader extends AbstractHeader {
+ public SymbolicNameHeader(String name, String value) {
+ super(name, value);
+ if (getClauses().size() != 1)
+ throw new IllegalArgumentException("Symbolic name headers must have one, and only one, clause: " + getClauses().size());
+ if (!Pattern.matches(Grammar.SYMBOLICNAME, getClauses().get(0).getPath()))
+ throw new IllegalArgumentException("Invalid symbolic name: " + getClauses().get(0).getPath());
+ }
+
+ public String getSymbolicName() {
+ return getClauses().get(0).getPath();
+ }
+}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java?rev=1241900&r1=1241899&r2=1241900&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/internal/Activator.java Wed Feb 8 13:54:41 2012
@@ -13,30 +13,20 @@
*/
package org.apache.aries.subsystem.core.internal;
+import static org.apache.aries.application.utils.AppConstants.LOG_ENTRY;
+import static org.apache.aries.application.utils.AppConstants.LOG_EXIT;
+
import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Dictionary;
-import java.util.Hashtable;
import java.util.List;
-import java.util.concurrent.Executor;
-import org.apache.felix.bundlerepository.RepositoryAdmin;
-import org.eclipse.equinox.region.RegionDigraph;
+import org.apache.felix.resolver.impl.ResolverImpl;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
+import org.osgi.framework.BundleListener;
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.hooks.resolver.ResolverHookFactory;
-import org.osgi.framework.wiring.FrameworkWiring;
-import org.osgi.service.coordinator.Coordinator;
-import org.osgi.service.event.EventAdmin;
-import org.osgi.service.event.EventConstants;
-import org.osgi.service.event.EventHandler;
-import org.osgi.service.repository.Repository;
import org.osgi.service.resolver.Resolver;
import org.osgi.service.subsystem.Subsystem;
-import org.osgi.util.tracker.ServiceTracker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -45,125 +35,79 @@ import org.slf4j.LoggerFactory;
* activator will create and register the SubsystemAdmin service.
*/
public class Activator implements BundleActivator {
- private static final Logger LOGGER = LoggerFactory.getLogger(Activator.class);
-
- private static BundleContext context;
-
- public static BundleContext getBundleContext() {
- return context;
- }
-
- public static Coordinator getCoordinator() {
- return context.getService(context.getServiceReference(Coordinator.class));
- }
-
- public static EventAdmin getEventAdmin() {
- ServiceReference<EventAdmin> ref = context.getServiceReference(EventAdmin.class);
- if (ref == null) return null;
- return context.getService(ref);
- }
-
- public static Executor getExecutor() {
- return context.getService(context.getServiceReference(Executor.class));
- }
+ private static final Logger logger = LoggerFactory.getLogger(Activator.class);
- public static FrameworkWiring getFrameworkWiring() {
- return context.getBundle(0).adapt(FrameworkWiring.class);
- }
+ private static Activator instance;
- public static RegionDigraph getRegionDigraph() {
- return context.getService(context.getServiceReference(RegionDigraph.class));
+ public static synchronized Activator getInstance() {
+ logger.debug(LOG_ENTRY, "getInstance");
+ checkInstance();
+ logger.debug(LOG_EXIT, "getInstance", instance);
+ return instance;
}
- public static Collection<Repository> getRepositories() {
- Collection<ServiceReference<Repository>> references;
- try {
- references = context.getServiceReferences(Repository.class, null);
- }
- catch (InvalidSyntaxException e) {
- // This should never happen, but I don't want to cover it up. Nor do I want to force clients to handle it.
- throw new RuntimeException(e);
- }
- ArrayList<Repository> repositories = new ArrayList<Repository>(references.size());
- for (ServiceReference<Repository> reference : references) {
- Repository repository = context.getService(reference);
- if (repository != null)
- repositories.add(repository);
- }
- repositories.trimToSize();
- return repositories;
+ private static synchronized void checkInstance() {
+ logger.debug(LOG_ENTRY, "checkInstance");
+ if (instance == null)
+ throw new IllegalStateException("The activator has not been initialized or has been shutdown");
+ logger.debug(LOG_EXIT, "checkInstance");
}
- public static RepositoryAdmin getRepositoryAdmin() {
- ServiceTracker st = new ServiceTracker(context, RepositoryAdmin.class.getName(), null);
- try {
- st.open();
- return (RepositoryAdmin)st.waitForService(5000);
- }
- catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- return null;
- }
- finally {
- st.close();
- }
- }
-
- /*
- * TODO
- * A naive implementation serving as a placeholder until a real Resolver comes along.
- */
- public static Resolver getResolver() {
-// return new SubsystemResolver();
- ServiceTracker st = new ServiceTracker(context, Resolver.class.getName(), null);
- try {
- st.open();
- return (Resolver)st.waitForService(5000);
- }
- catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- return null;
- }
- finally {
- st.close();
- }
- }
-
-// private final BundleListener bundleListener = new SubsystemSynchronousBundleListener();
+ private final BundleListener bundleListener = new SubsystemSynchronousBundleListener();
private final List<ServiceRegistration<?>> registrations = new ArrayList<ServiceRegistration<?>>();
- public void start(final BundleContext context) throws Exception {
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("subsystem activator starting");
- }
- Activator.context = context;
- register(Subsystem.class.getName(), new SubsystemServiceFactory(), null);
- register(ResolverHookFactory.class, new SubsystemResolverHookFactory(), null);
-// context.getBundle(0).getBundleContext().addBundleListener(bundleListener);
- Dictionary<String, Object> properties = new Hashtable<String, Object>();
- properties.put(EventConstants.EVENT_TOPIC, new String[]{"org/osgi/framework/BundleEvent/*"});
- register(EventHandler.class, new BundleEventHandler(), properties);
- }
-
- public void stop(BundleContext context) throws Exception {
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("subsystem activator stopping");
- }
-// context.getBundle(0).getBundleContext().removeBundleListener(bundleListener);
- for (ServiceRegistration<?> r : registrations) {
+ private BundleContext bundleContext;
+ private ServiceProviderImpl serviceProvider;
+
+ public synchronized BundleContext getBundleContext() {
+ logger.debug(LOG_ENTRY, "getBundleContext");
+ BundleContext result = bundleContext;
+ logger.debug(LOG_EXIT, "getBundleContext", result);
+ return result;
+ }
+
+ public synchronized ServiceProvider getServiceProvider() {
+ logger.debug(LOG_ENTRY, "getServiceProvider");
+ ServiceProvider result = serviceProvider;
+ logger.debug(LOG_EXIT, "getServiceProvider", result);
+ return result;
+ }
+
+ @Override
+ public synchronized void start(final BundleContext context) throws Exception {
+ logger.debug(LOG_ENTRY, "start", context);
+ synchronized (Activator.class) {
+ instance = this;
+ }
+ bundleContext = context;
+ serviceProvider = new ServiceProviderImpl(bundleContext);
+ context.getBundle(0).getBundleContext().addBundleListener(bundleListener);
+ registrations.add(bundleContext.registerService(ResolverHookFactory.class, new SubsystemResolverHookFactory(), null));
+ // TODO The registration of the Resolver service should be temporary, unless Felix
+ // does not have an official release at the time.
+ registrations.add(bundleContext.registerService(Resolver.class, new ResolverImpl(null), null));
+ AriesSubsystem root = new AriesSubsystem();
+ registrations.add(bundleContext.registerService(Subsystem.class.getName(), root, null));
+ root.install();
+ logger.debug(LOG_EXIT, "start");
+ }
+
+ @Override
+ public synchronized void stop(BundleContext context) /*throws Exception*/ {
+ logger.debug(LOG_ENTRY, "stop", context);
+ for (int i = registrations.size() - 1; i >= 0; i--) {
try {
- r.unregister();
- } catch (Exception e) {
- LOGGER.warn("Subsystem Activator shut down", e);
+ registrations.get(i).unregister();
+ }
+ catch (IllegalStateException e) {
+ logger.debug("Service had already been unregistered", e);
}
}
- }
-
- private <T> void register(Class<T> clazz, T service, Dictionary<String, ?> props) {
- registrations.add(context.registerService(clazz.getName(), service, props));
- }
-
- private <T> void register(String clazz, T service, Dictionary<String, ?> props) {
- registrations.add(context.registerService(clazz, service, props));
+ context.getBundle(0).getBundleContext().removeBundleListener(bundleListener);
+ serviceProvider.shutdown();
+ synchronized (Activator.class) {
+ instance = null;
+ }
+ logger.debug(LOG_EXIT, "stop");
}
}