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 [5/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-...
Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/SubsystemEnvironment.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/SubsystemEnvironment.java?rev=1241900&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/SubsystemEnvironment.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/SubsystemEnvironment.java Wed Feb 8 13:54:41 2012
@@ -0,0 +1,256 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.aries.subsystem.core.obr;
+
+import static org.apache.aries.application.utils.AppConstants.LOG_ENTRY;
+import static org.apache.aries.application.utils.AppConstants.LOG_EXIT;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.aries.subsystem.core.ResourceHelper;
+import org.apache.aries.subsystem.core.internal.Activator;
+import org.apache.aries.subsystem.core.internal.AriesSubsystem;
+import org.apache.aries.subsystem.core.internal.OsgiIdentityRequirement;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.resource.Capability;
+import org.osgi.framework.resource.Requirement;
+import org.osgi.framework.resource.Resource;
+import org.osgi.framework.resource.Wiring;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.service.repository.Repository;
+import org.osgi.service.resolver.Environment;
+import org.osgi.service.subsystem.Subsystem;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/*
+ * TODO
+ * The locating of providers for transitive dependencies needs to have subsystem type and share policies taken into account.
+ * So does the locating of providers for feature content with respect to children of the first parent that is not a feature.
+ */
+public class SubsystemEnvironment implements Environment {
+ private static final Logger logger = LoggerFactory.getLogger(SubsystemEnvironment.class);
+
+ private final Set<Resource> resources = new HashSet<Resource>();
+ private final AriesSubsystem subsystem;
+
+ public SubsystemEnvironment(AriesSubsystem subsystem) throws IOException, URISyntaxException {
+ this.subsystem = subsystem;
+ }
+
+ @Override
+ public SortedSet<Capability> findProviders(Requirement requirement) {
+ logger.debug(LOG_ENTRY, "findProviders", requirement);
+ // TODO Need a more robust comparator. This is just a temporary place holder.
+ SortedSet<Capability> capabilities = new TreeSet<Capability>(
+ new Comparator<Capability>() {
+ @Override
+ public int compare(Capability capability1, Capability capability2) {
+ if (logger.isDebugEnabled())
+ logger.debug(LOG_ENTRY, "compare", new Object[]{capability1, capability2});
+ int result = 0;
+ boolean br1 = capability1.getResource() instanceof BundleRevision;
+ boolean br2 = capability2.getResource() instanceof BundleRevision;
+ if (br1 && !br2)
+ result = -1;
+ if (!br1 && br2)
+ result = 1;
+ logger.debug(LOG_EXIT, "compare", result);
+ return result;
+ }
+ });
+ if (requirement instanceof OsgiIdentityRequirement) {
+ logger.debug("The requirement is an instance of OsgiIdentityRequirement");
+ // TODO Consider returning only the first capability matched by the requirement in this case.
+ // This means we're looking for a content resource.
+ OsgiIdentityRequirement identity = (OsgiIdentityRequirement)requirement;
+ if (subsystem.isFeature()) {
+ // Features share content resources as well as transitive dependencies.
+ findConstituentProviders(requirement, capabilities);
+ }
+ findArchiveProviders(capabilities, identity, !identity.isTransitiveDependency());
+ findRepositoryServiceProviders(capabilities, identity, !identity.isTransitiveDependency());
+ }
+ else {
+ logger.debug("The requirement is NOT an instance of OsgiIdentityRequirement");
+ // This means we're looking for capabilities satisfying a requirement within a content resource or transitive dependency.
+ findArchiveProviders(capabilities, requirement, false);
+ findRepositoryServiceProviders(capabilities, requirement, false);
+ // TODO The following is a quick fix to ensure this environment always returns capabilities provided by the system bundle. Needs some more thought.
+ findConstituentProviders(requirement, capabilities);
+ }
+ logger.debug(LOG_EXIT, "findProviders", capabilities);
+ return capabilities;
+ }
+
+ @Override
+ public Map<Requirement, SortedSet<Capability>> findProviders(Collection<? extends Requirement> requirements) {
+ logger.debug(LOG_ENTRY, "findProviders", requirements);
+ Map<Requirement, SortedSet<Capability>> result = new HashMap<Requirement, SortedSet<Capability>>(requirements.size());
+ for (Requirement requirement : requirements)
+ result.put(requirement, findProviders(requirement));
+ logger.debug(LOG_EXIT, "findProviders", result);
+ return result;
+ }
+
+ public Resource findResource(OsgiIdentityRequirement requirement) {
+ logger.debug(LOG_ENTRY, "findResource", requirement);
+ Collection<Capability> capabilities = findProviders(requirement);
+ Resource result = null;
+ if (!capabilities.isEmpty())
+ result = capabilities.iterator().next().getResource();
+ logger.debug(LOG_EXIT, "findResource", result);
+ return result;
+ }
+
+ @Override
+ public Map<Resource, Wiring> getWirings() {
+ logger.debug(LOG_ENTRY, "getWirings");
+ Map<Resource, Wiring> result = new HashMap<Resource, Wiring>();
+ BundleContext bundleContext = Activator.getInstance().getBundleContext().getBundle(0).getBundleContext();
+ for (Bundle bundle : bundleContext.getBundles()) {
+ BundleRevision revision = bundle.adapt(BundleRevision.class);
+ Wiring wiring = revision.getWiring();
+ if (wiring != null) {
+ result.put(
+ revision,
+ revision.getWiring());
+ }
+ }
+ logger.debug(LOG_EXIT, "getWirings", result);
+ return result;
+ }
+
+ public boolean isContentResource(Resource resource) {
+ logger.debug(LOG_ENTRY, "isContentResource", resource);
+ boolean result = resources.contains(resource);
+ logger.debug(LOG_EXIT, "isContentResource", result);
+ return result;
+ }
+
+ @Override
+ public boolean isEffective(Requirement requirement) {
+ logger.debug(LOG_ENTRY, "isEffective", requirement);
+ boolean result = true;
+ logger.debug(LOG_EXIT, "isEffective", result);
+ return true;
+ }
+
+ private void findConstituentProviders(Requirement requirement, Collection<Capability> capabilities) {
+ if (logger.isDebugEnabled())
+ logger.debug(LOG_ENTRY, "findConstituentProviders", new Object[]{requirement, capabilities});
+ Subsystem subsystem = this.subsystem;
+ logger.debug("Navigating up the parent hierarchy...");
+ while (!subsystem.getParents().isEmpty()) {
+ subsystem = subsystem.getParents().iterator().next();
+ logger.debug("Next parent is: {}", subsystem);
+ }
+ findConstituentProviders(subsystem, requirement, capabilities);
+ logger.debug(LOG_EXIT, "findConstituentProviders");
+ }
+
+ private void findConstituentProviders(Subsystem subsystem, Requirement requirement, Collection<Capability> capabilities) {
+ if (logger.isDebugEnabled())
+ logger.debug(LOG_ENTRY, "findConstituentProviders", new Object[]{subsystem, requirement, capabilities});
+ for (Resource resource : subsystem.getConstituents()) {
+ 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);
+ }
+ }
+ }
+ findConstituentProviders(subsystem.getChildren(), requirement, capabilities);
+ logger.debug(LOG_EXIT, "findConstituentProviders");
+ }
+
+ private void findConstituentProviders(Collection<Subsystem> children, Requirement requirement, Collection<Capability> capabilities) {
+ if (logger.isDebugEnabled())
+ logger.debug(LOG_ENTRY, "findConstituentProviders", new Object[]{children, requirement, capabilities});
+ for (Subsystem child : children) {
+ logger.debug("Evaluating child subsystem: {}", child);
+ findConstituentProviders(child, requirement, capabilities);
+ }
+ }
+
+ private void findArchiveProviders(Collection<Capability> capabilities, Requirement requirement, boolean content) {
+ if (logger.isDebugEnabled())
+ logger.debug(LOG_ENTRY, "findArchiveProviders", new Object[]{capabilities, requirement, content});
+ AriesSubsystem subsystem = this.subsystem;
+ logger.debug("Navigating up the parent hierarchy...");
+ while (!subsystem.getParents().isEmpty()) {
+ subsystem = (AriesSubsystem)subsystem.getParents().iterator().next();
+ logger.debug("Next parent is: {}", subsystem);
+ }
+ findArchiveProviders(capabilities, requirement, subsystem, content);
+ logger.debug(LOG_EXIT, "findArchiveProviders");
+ }
+
+ private void findArchiveProviders(Collection<Capability> capabilities, Requirement requirement, AriesSubsystem subsystem, boolean content) {
+ if (logger.isDebugEnabled())
+ logger.debug(LOG_ENTRY, "findArchiveProviders", new Object[]{capabilities, requirement, subsystem, content});
+ for (Capability capability : subsystem.getArchive().findProviders(requirement)) {
+ logger.debug("Adding capability: {}", capability);
+ capabilities.add(capability);
+ if (content) {
+ Resource resource = capability.getResource();
+ logger.debug("Adding content resource: {}", resource);
+ resources.add(resource);
+ }
+ }
+ findArchiveProviders(capabilities, requirement, subsystem.getChildren(), content);
+ logger.debug(LOG_EXIT, "findArchiveProviders");
+ }
+
+ private void findArchiveProviders(Collection<Capability> capabilities, Requirement requirement, Collection<Subsystem> children, boolean content) {
+ if (logger.isDebugEnabled())
+ logger.debug(LOG_ENTRY, "findArchiveProviders", new Object[]{capabilities, requirement, children, content});
+ for (Subsystem child : children) {
+ logger.debug("Evaluating child subsystem: {}", child);
+ findArchiveProviders(capabilities, requirement, (AriesSubsystem)child, content);
+ }
+ logger.debug(LOG_EXIT, "findArchiveProviders");
+ }
+
+ private void findRepositoryServiceProviders(Collection<Capability> capabilities, Requirement requirement, boolean content) {
+ if (logger.isDebugEnabled())
+ logger.debug(LOG_ENTRY, "findRepositoryServiceProviders", new Object[]{capabilities, requirement, content});
+ Collection<Repository> repositories = Activator.getInstance().getServiceProvider().getServices(Repository.class);
+ for (Repository repository : repositories) {
+ logger.debug("Evaluating repository: {}", repository);
+ for (Capability capability : repository.findProviders(requirement)) {
+ logger.debug("Adding capability: {}", capability);
+ capabilities.add(capability);
+ if (content) {
+ Resource resource = capability.getResource();
+ logger.debug("Adding content resource: {}", resource);
+ resources.add(resource);
+ }
+ }
+ }
+ logger.debug(LOG_EXIT, "findRepositoryServiceProviders");
+ }
+}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/SubsystemResolver.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/SubsystemResolver.java?rev=1241900&r1=1241899&r2=1241900&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/SubsystemResolver.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/SubsystemResolver.java Wed Feb 8 13:54:41 2012
@@ -13,6 +13,9 @@
*/
package org.apache.aries.subsystem.core.obr;
+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.Collections;
@@ -21,25 +24,31 @@ import java.util.List;
import java.util.Map;
import org.apache.aries.subsystem.core.internal.Activator;
-import org.apache.aries.subsystem.core.internal.OsgiIdentityRequirement;
-import org.apache.aries.subsystem.core.obr.felix.FelixResourceAdapter;
import org.apache.aries.subsystem.core.obr.felix.OsgiResourceAdapter;
import org.apache.felix.bundlerepository.Reason;
+import org.apache.felix.bundlerepository.RepositoryAdmin;
import org.osgi.framework.resource.Capability;
import org.osgi.framework.resource.Requirement;
import org.osgi.framework.resource.Resource;
import org.osgi.framework.resource.Wire;
+import org.osgi.framework.resource.Wiring;
import org.osgi.service.resolver.Environment;
import org.osgi.service.resolver.ResolutionException;
import org.osgi.service.resolver.Resolver;
import org.osgi.service.subsystem.SubsystemException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class SubsystemResolver implements Resolver {
+ private static final Logger logger = LoggerFactory.getLogger(SubsystemResolver.class);
+
private static void addCapabilities(Collection<Capability> capabilities, Environment environment, Requirement requirement) {
Collection<Capability> caps = environment.findProviders(requirement);
if (caps.isEmpty())
return;
Capability capability = caps.iterator().next();
+ if (capabilities.contains(capability))
+ return;
capabilities.add(capability);
addCapabilities(capabilities, environment, capability.getResource().getRequirements(null));
}
@@ -51,7 +60,9 @@ public class SubsystemResolver implement
}
@Override
- public Map<Resource, List<Wire>> resolve(Environment environment, Collection<Resource> mandatory, Collection<Resource> optional) throws ResolutionException {
+ public Map<Resource, List<Wire>> resolve(Environment environment, Collection<? extends Resource> mandatory, Collection<? extends Resource> optional) throws ResolutionException {
+ if (logger.isDebugEnabled())
+ logger.debug(LOG_ENTRY, "resolve", new Object[]{environment, mandatory, optional});
Collection<Capability> capabilities = new ArrayList<Capability>();
/*
* TODO Until an implementation of Resolver comes along, need to find as many resources with capabilities satisfying as
@@ -71,30 +82,31 @@ public class SubsystemResolver implement
for (Capability capability : capabilities) {
resources.add(capability.getResource());
}
- org.apache.felix.bundlerepository.Resolver resolver = Activator.getRepositoryAdmin().resolver();
+ org.apache.felix.bundlerepository.Resolver resolver = Activator.getInstance().getServiceProvider().getService(RepositoryAdmin.class).resolver();
for (Resource resource : resources) {
resolver.add(new OsgiResourceAdapter(resource));
}
- if (resolver.resolve()) {
- /*
- * TODO For now, these need to go back through the environment in order to be sure the URL is available.
- * This is because RepositoryAdmin is not going through the environment as part of pulling in transitive
- * dependencies. Once a "real" Resolver is available, this will no longer be necessary.
- */
- for (org.apache.felix.bundlerepository.Resource resource : resolver.getRequiredResources()) {
- Resource r = new FelixResourceAdapter(resource);
- // Make the environment aware of the resource and its URL.
- environment.findProviders(new OsgiIdentityRequirement(r, true));
- resources.add(r);
- }
- for (org.apache.felix.bundlerepository.Resource resource : resolver.getOptionalResources()) {
- Resource r = new FelixResourceAdapter(resource);
- // Make the environment aware of the resource and its URL.
- environment.findProviders(new OsgiIdentityRequirement(r, true));
- resources.add(r);
- }
- }
- else {
+// if (resolver.resolve()) {
+// /*
+// * TODO For now, these need to go back through the environment in order to be sure the URL is available.
+// * This is because RepositoryAdmin is not going through the environment as part of pulling in transitive
+// * dependencies. Once a "real" Resolver is available, this will no longer be necessary.
+// */
+// for (org.apache.felix.bundlerepository.Resource resource : resolver.getRequiredResources()) {
+// Resource r = new FelixResourceAdapter(resource);
+// // Make the environment aware of the resource and its URL.
+// environment.findProviders(new OsgiIdentityRequirement(r, true));
+// resources.add(r);
+// }
+// for (org.apache.felix.bundlerepository.Resource resource : resolver.getOptionalResources()) {
+// Resource r = new FelixResourceAdapter(resource);
+// // Make the environment aware of the resource and its URL.
+// environment.findProviders(new OsgiIdentityRequirement(r, true));
+// resources.add(r);
+// }
+// }
+// else {
+ if (!resolver.resolve()) {
Reason[] reasons = resolver.getUnsatisfiedRequirements();
StringBuilder builder = new StringBuilder("Failed to resolve subsystem").append(System.getProperty("line.separator"));
for (Reason reason : reasons)
@@ -111,6 +123,7 @@ public class SubsystemResolver implement
for (Resource resource : resources) {
result.put(resource, Collections.EMPTY_LIST);
}
+ logger.debug(LOG_EXIT, "resolve", result);
return result;
}
}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/FelixCapabilityAdapter.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/FelixCapabilityAdapter.java?rev=1241900&r1=1241899&r2=1241900&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/FelixCapabilityAdapter.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/FelixCapabilityAdapter.java Wed Feb 8 13:54:41 2012
@@ -16,19 +16,17 @@ package org.apache.aries.subsystem.core.
import java.util.Collections;
import java.util.Map;
-import org.osgi.framework.resource.Capability;
+import org.apache.aries.subsystem.core.resource.AbstractCapability;
import org.osgi.framework.resource.Resource;
import org.osgi.framework.wiring.BundleRevision;
-public class FelixCapabilityAdapter implements Capability {
+public class FelixCapabilityAdapter extends AbstractCapability {
private final org.apache.felix.bundlerepository.Capability capability;
private final Resource resource;
public FelixCapabilityAdapter(org.apache.felix.bundlerepository.Capability capability, Resource resource) {
if (capability == null)
throw new NullPointerException("Missing required parameter: capability");
- if (resource == null)
- throw new NullPointerException("Missing required parameter: resource");
this.capability = capability;
this.resource = resource;
}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/FelixRepositoryAdapter.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/FelixRepositoryAdapter.java?rev=1241900&r1=1241899&r2=1241900&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/FelixRepositoryAdapter.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/FelixRepositoryAdapter.java Wed Feb 8 13:54:41 2012
@@ -13,55 +13,142 @@
*/
package org.apache.aries.subsystem.core.obr.felix;
-import java.net.URI;
-import java.net.URL;
+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.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.apache.aries.subsystem.core.ResourceHelper;
+import org.apache.aries.subsystem.core.internal.OsgiIdentityCapability;
+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.subsystem.SubsystemException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class FelixRepositoryAdapter implements Repository {
+ private static class IdentityRequirementFilter {
+ private static final String REGEX = "\\(osgi.identity=([^\\)]*)\\)";
+ private static final Pattern PATTERN = Pattern.compile(REGEX);
+
+ private final String symbolicName;
+
+ public IdentityRequirementFilter(String filter) {
+ Matcher matcher = PATTERN.matcher(filter);
+ if (!matcher.find())
+ throw new IllegalArgumentException("Could not find pattern '" + REGEX + "' in filter string '" + filter + "'");
+ symbolicName = matcher.group(1);
+ }
+
+ public String getSymbolicName() {
+ return symbolicName;
+ }
+ }
+
+ private static final Logger logger = LoggerFactory.getLogger(FelixRepositoryAdapter.class);
+
+ private final Map<String, Collection<Capability>> identityIndex = Collections.synchronizedMap(new HashMap<String, Collection<Capability>>());
private final org.apache.felix.bundlerepository.Repository repository;
+ private long lastUpdated = 0;
+
public FelixRepositoryAdapter(org.apache.felix.bundlerepository.Repository repository) {
+ if (repository == null)
+ throw new NullPointerException("Missing required parameter: repository");
this.repository = repository;
}
@Override
- public Collection<Capability> findProviders(Requirement requirement) throws NullPointerException {
- org.apache.felix.bundlerepository.Resource[] resources = repository.getResources();
- ArrayList<Capability> result = new ArrayList<Capability>(resources.length);
- for (final org.apache.felix.bundlerepository.Resource resource : resources) {
- Resource r = new FelixResourceAdapter(resource);
- for (Capability capability : r.getCapabilities(requirement.getNamespace()))
- if (requirement.matches(capability))
- result.add(capability);
+ public Collection<Capability> findProviders(Requirement requirement) {
+ logger.debug(LOG_ENTRY, "findProviders", requirement);
+ update();
+ List<Capability> result = Collections.emptyList();
+ if (ResourceConstants.IDENTITY_NAMESPACE.equals(requirement.getNamespace())) {
+ String symbolicName = new IdentityRequirementFilter(requirement.getDirectives().get(Constants.FILTER_DIRECTIVE)).getSymbolicName();
+ logger.debug("Looking for symbolic name {}", symbolicName);
+ Collection<Capability> capabilities = identityIndex.get(symbolicName);
+ if (capabilities != null) {
+ result = new ArrayList<Capability>(capabilities.size());
+ for (Capability capability : capabilities) {
+ if (ResourceHelper.matches(requirement, capability)) {
+ result.add(capability);
+ }
+ }
+ ((ArrayList<Capability>)result).trimToSize();
+ }
}
- result.trimToSize();
+ else {
+ org.apache.felix.bundlerepository.Resource[] resources = repository.getResources();
+ if (resources != null && resources.length != 0) {
+ result = new ArrayList<Capability>(resources.length);
+ for (final org.apache.felix.bundlerepository.Resource resource : resources) {
+ Resource r = new FelixResourceAdapter(resource);
+ for (Capability capability : r.getCapabilities(requirement.getNamespace()))
+ if (ResourceHelper.matches(requirement, capability))
+ result.add(capability);
+ }
+ ((ArrayList<Capability>)result).trimToSize();
+ }
+ }
+ logger.debug(LOG_EXIT, "findProviders", result);
return result;
}
-
+
@Override
- public URL getContent(Resource resource) {
- for (final org.apache.felix.bundlerepository.Resource r : repository.getResources()) {
- final Resource sr = new FelixResourceAdapter(r);
- if (ResourceHelper.getTypeAttribute(resource).equals(ResourceHelper.getTypeAttribute(sr)))
- if (ResourceHelper.getSymbolicNameAttribute(resource).equals(ResourceHelper.getSymbolicNameAttribute(sr)))
- if (ResourceHelper.getVersionAttribute(resource).equals(ResourceHelper.getVersionAttribute(sr))) {
- try {
- return new URI(r.getURI()).toURL();
- }
- catch (Exception e) {
- // TODO Is this really what we want to do?
- throw new SubsystemException(e);
+ public Map<Requirement, Collection<Capability>> findProviders(Collection<? extends Requirement> requirements) {
+ logger.debug(LOG_ENTRY, "findProviders", requirements);
+ Map<Requirement, Collection<Capability>> result = new HashMap<Requirement, Collection<Capability>>(requirements.size());
+ for (Requirement requirement : requirements)
+ result.put(requirement, findProviders(requirement));
+ logger.debug(LOG_EXIT, "findProviders", result);
+ return result;
+ }
+
+ private synchronized void update() {
+ logger.debug(LOG_ENTRY, "update");
+ long lastModified = repository.getLastModified();
+ logger.debug("The repository adaptor was last updated at {}. The repository was last modified at {}", lastUpdated, lastModified);
+ if (lastModified > lastUpdated) {
+ logger.debug("Updating the adapter with the modified repository contents...");
+ lastUpdated = lastModified;
+ synchronized (identityIndex) {
+ identityIndex.clear();
+ org.apache.felix.bundlerepository.Resource[] resources = repository.getResources();
+ logger.debug("There are {} resources to evaluate", resources == null ? 0 : resources.length);
+ if (resources != null && resources.length != 0) {
+ for (org.apache.felix.bundlerepository.Resource resource : resources) {
+ logger.debug("Evaluating resource {}", resource);
+ String symbolicName = resource.getSymbolicName();
+ Collection<Capability> capabilities = identityIndex.get(symbolicName);
+ if (capabilities == null) {
+ capabilities = new HashSet<Capability>();
+ identityIndex.put(symbolicName, capabilities);
}
+ OsgiIdentityCapability capability =
+ new OsgiIdentityCapability(
+ new FelixResourceAdapter(resource),
+ symbolicName,
+ resource.getVersion(),
+ // TODO Assuming all resources are bundles. Need to support
+ // type fragment as well, but how do we know?
+ ResourceConstants.IDENTITY_TYPE_BUNDLE);
+ logger.debug("Indexing capability {}", capability);
+ capabilities.add(capability);
}
+ }
+ }
}
- return null;
+ logger.debug(LOG_EXIT, "update");
}
}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/FelixResourceAdapter.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/FelixResourceAdapter.java?rev=1241900&r1=1241899&r2=1241900&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/FelixResourceAdapter.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/FelixResourceAdapter.java Wed Feb 8 13:54:41 2012
@@ -13,6 +13,9 @@
*/
package org.apache.aries.subsystem.core.obr.felix;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
import java.util.ArrayList;
import java.util.List;
@@ -24,8 +27,9 @@ import org.osgi.framework.resource.Requi
import org.osgi.framework.resource.Resource;
import org.osgi.framework.resource.ResourceConstants;
import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.service.repository.RepositoryContent;
-public class FelixResourceAdapter implements Resource {
+public class FelixResourceAdapter implements Resource, RepositoryContent {
private static String toFelixNamespace(String namespace) {
if (BundleRevision.BUNDLE_NAMESPACE.equals(namespace))
return org.apache.felix.bundlerepository.Capability.BUNDLE;
@@ -91,6 +95,11 @@ public class FelixResourceAdapter implem
result.trimToSize();
return result;
}
+
+ @Override
+ public InputStream getContent() throws IOException {
+ return new URL(resource.getURI()).openStream();
+ }
public List<Requirement> getRequirements(String namespace) {
namespace = toFelixNamespace(namespace);
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/OsgiCapabilityAdapter.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/OsgiCapabilityAdapter.java?rev=1241900&r1=1241899&r2=1241900&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/OsgiCapabilityAdapter.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/OsgiCapabilityAdapter.java Wed Feb 8 13:54:41 2012
@@ -30,6 +30,11 @@ public class OsgiCapabilityAdapter imple
throw new NullPointerException("Missing required parameter: capability");
this.capability = capability;
}
+
+ @Override
+ public boolean equals(Object o) {
+ return capability.equals(o);
+ }
public String getName() {
String namespace = capability.getNamespace();
@@ -61,4 +66,9 @@ public class OsgiCapabilityAdapter imple
result.put(getName(), result.get(capability.getNamespace()));
return result;
}
+
+ @Override
+ public int hashCode() {
+ return capability.hashCode();
+ }
}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/OsgiRequirementAdapter.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/OsgiRequirementAdapter.java?rev=1241900&r1=1241899&r2=1241900&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/OsgiRequirementAdapter.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/OsgiRequirementAdapter.java Wed Feb 8 13:54:41 2012
@@ -13,12 +13,20 @@
*/
package org.apache.aries.subsystem.core.obr.felix;
+import static org.apache.aries.application.utils.AppConstants.LOG_ENTRY;
+import static org.apache.aries.application.utils.AppConstants.LOG_EXIT;
+
+import org.apache.aries.subsystem.core.ResourceHelper;
import org.apache.felix.bundlerepository.Capability;
import org.apache.felix.bundlerepository.Requirement;
import org.osgi.framework.Constants;
import org.osgi.framework.wiring.BundleRevision;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class OsgiRequirementAdapter implements Requirement {
+ private static final Logger logger = LoggerFactory.getLogger(OsgiRequirementAdapter.class);
+
private final org.osgi.framework.resource.Requirement requirement;
public OsgiRequirementAdapter(org.osgi.framework.resource.Requirement requirement) {
@@ -60,7 +68,10 @@ public class OsgiRequirementAdapter impl
}
public boolean isSatisfied(Capability capability) {
- return requirement.matches(new FelixCapabilityAdapter(capability, requirement.getResource()));
+ logger.debug(LOG_ENTRY, "isSatisfied", capability);
+ boolean result = ResourceHelper.matches(requirement, new FelixCapabilityAdapter(capability, null));
+ logger.debug(LOG_EXIT, "isSatisfied", result);
+ return result;
}
}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/RepositoryAdminRepository.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/RepositoryAdminRepository.java?rev=1241900&r1=1241899&r2=1241900&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/RepositoryAdminRepository.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/RepositoryAdminRepository.java Wed Feb 8 13:54:41 2012
@@ -13,43 +13,80 @@
*/
package org.apache.aries.subsystem.core.obr.felix;
-import java.net.URL;
+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.Collections;
+import java.util.HashMap;
+import java.util.Map;
import org.apache.felix.bundlerepository.RepositoryAdmin;
+import org.apache.felix.bundlerepository.Resource;
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 RepositoryAdminRepository implements Repository {
+ private static final Logger logger = LoggerFactory.getLogger(RepositoryAdminRepository.class);
+
+ private Collection<Repository> repositories = new ArrayList<Repository>();
private final RepositoryAdmin repositoryAdmin;
public RepositoryAdminRepository(RepositoryAdmin repositoryAdmin) {
+ org.apache.felix.bundlerepository.Repository[] repositories = repositoryAdmin.listRepositories();
+ for (org.apache.felix.bundlerepository.Repository repository : repositories) {
+ FelixRepositoryAdapter r = new FelixRepositoryAdapter(repository);
+ this.repositories.add(r);
+ }
this.repositoryAdmin = repositoryAdmin;
}
@Override
public Collection<Capability> findProviders(Requirement requirement) {
- org.apache.felix.bundlerepository.Repository[] repositories = repositoryAdmin.listRepositories();
- ArrayList<Capability> result = new ArrayList<Capability>();
- for (org.apache.felix.bundlerepository.Repository repository : repositories) {
- FelixRepositoryAdapter r = new FelixRepositoryAdapter(repository);
- result.addAll(r.findProviders(requirement));
+ logger.debug(LOG_ENTRY, "findProviders", requirement);
+ Collection<Capability> result = Collections.emptyList();
+ if (ResourceConstants.IDENTITY_NAMESPACE.equals(requirement.getNamespace())) {
+ result = new ArrayList<Capability>();
+ for (Repository repository : repositories) {
+ result.addAll(repository.findProviders(requirement));
+ }
+ return result;
}
+ else {
+ Resource[] resources = repositoryAdmin.discoverResources(
+ new org.apache.felix.bundlerepository.Requirement[]{
+ new OsgiRequirementAdapter(requirement)});
+ logger.debug("Found {} resources with capabilities satisfying {}", resources == null ? 0 : resources.length, requirement);
+ if (resources != null && resources.length != 0) {
+ result = new ArrayList<Capability>(result.size());
+ OsgiRequirementAdapter adapter = new OsgiRequirementAdapter(requirement);
+ for (Resource resource : resources) {
+ logger.debug("Evaluating resource {}", resource);
+ for (org.apache.felix.bundlerepository.Capability capability : resource.getCapabilities()) {
+ logger.debug("Evaluating capability {}", capability);
+ if (adapter.isSatisfied(capability)) {
+ logger.debug("Adding capability {}", capability);
+ result.add(new FelixCapabilityAdapter(capability, new FelixResourceAdapter(resource)));
+ }
+ }
+ }
+ }
+ }
+ logger.debug(LOG_EXIT, "findProviders", result);
return result;
- }
+ }
+
@Override
- public URL getContent(Resource resource) {
- org.apache.felix.bundlerepository.Repository[] repositories = repositoryAdmin.listRepositories();
- for (org.apache.felix.bundlerepository.Repository repository : repositories) {
- FelixRepositoryAdapter r = new FelixRepositoryAdapter(repository);
- URL url = r.getContent(resource);
- if (url != null)
- return url;
- }
- return null;
+ 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;
}
}
Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/AbstractCapability.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/AbstractCapability.java?rev=1241900&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/AbstractCapability.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/AbstractCapability.java Wed Feb 8 13:54:41 2012
@@ -0,0 +1,38 @@
+package org.apache.aries.subsystem.core.resource;
+
+import org.osgi.framework.resource.Capability;
+
+public abstract class AbstractCapability implements Capability {
+ @Override
+ public boolean equals(Object o) {
+ if (o == this)
+ return true;
+ if (!(o instanceof Capability))
+ return false;
+ Capability c = (Capability)o;
+ return c.getNamespace().equals(getNamespace())
+ && c.getAttributes().equals(getAttributes())
+ && c.getDirectives().equals(getDirectives())
+ && c.getResource().equals(getResource());
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 17;
+ result = 31 * result + getNamespace().hashCode();
+ result = 31 * result + getAttributes().hashCode();
+ result = 31 * result + getDirectives().hashCode();
+ result = 31 * result + getResource().hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuffer().append("[Capability: ")
+ .append("namespace=").append(getNamespace())
+ .append(", attributes=").append(getAttributes())
+ .append(", directives=").append(getDirectives())
+ .append(", resource=").append(getResource()).append(']')
+ .toString();
+ }
+}
Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/AbstractRequirement.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/AbstractRequirement.java?rev=1241900&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/AbstractRequirement.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/AbstractRequirement.java Wed Feb 8 13:54:41 2012
@@ -0,0 +1,41 @@
+package org.apache.aries.subsystem.core.resource;
+
+import org.osgi.framework.resource.Capability;
+import org.osgi.framework.resource.Requirement;
+
+public abstract class AbstractRequirement implements Requirement {
+ @Override
+ public boolean equals(Object o) {
+ if (o == this)
+ return true;
+ if (!(o instanceof Requirement))
+ return false;
+ Requirement c = (Requirement)o;
+ return c.getNamespace().equals(getNamespace())
+ && c.getAttributes().equals(getAttributes())
+ && c.getDirectives().equals(getDirectives())
+ && c.getResource() != null ? c.getResource().equals(
+ getResource()) : getResource() == null;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 17;
+ result = 31 * result + getNamespace().hashCode();
+ result = 31 * result + getAttributes().hashCode();
+ result = 31 * result + getDirectives().hashCode();
+ result = 31 * result
+ + (getResource() == null ? 0 : getResource().hashCode());
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuffer().append("[Requirement: ")
+ .append("namespace=").append(getNamespace())
+ .append(", attributes=").append(getAttributes())
+ .append(", directives=").append(getDirectives())
+ .append(", resource=").append(getResource()).append(']')
+ .toString();
+ }
+}
Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/BasicCapability.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/BasicCapability.java?rev=1241900&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/BasicCapability.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/BasicCapability.java Wed Feb 8 13:54:41 2012
@@ -0,0 +1,51 @@
+package org.apache.aries.subsystem.core.resource;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.osgi.framework.resource.Resource;
+
+public class BasicCapability extends AbstractCapability {
+ private final Map<String, Object> attributes;
+ private final Map<String, String> directives;
+ private final Resource resource;
+ private final String namespace;
+
+ public BasicCapability(String namespace, Map<String, Object> attributes, Map<String, String> directives, Resource resource) {
+ if (namespace == null)
+ throw new NullPointerException();
+ this.namespace = namespace;
+ if (attributes == null)
+ this.attributes = Collections.emptyMap();
+ else
+ this.attributes = Collections.unmodifiableMap(new HashMap<String, Object>(attributes));
+ if (directives == null)
+ this.directives = Collections.emptyMap();
+ else
+ this.directives = Collections.unmodifiableMap(new HashMap<String, String>(directives));
+ if (resource == null)
+ throw new NullPointerException();
+ this.resource = resource;
+ }
+
+ @Override
+ public Map<String, Object> getAttributes() {
+ return attributes;
+ }
+
+ @Override
+ public Map<String, String> getDirectives() {
+ return directives;
+ }
+
+ @Override
+ public String getNamespace() {
+ return namespace;
+ }
+
+ @Override
+ public Resource getResource() {
+ return resource;
+ }
+}
Modified: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/BundleResource.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/BundleResource.java?rev=1241900&r1=1241899&r2=1241900&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/BundleResource.java (original)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/BundleResource.java Wed Feb 8 13:54:41 2012
@@ -28,8 +28,9 @@ import org.apache.aries.subsystem.core.i
import org.osgi.framework.resource.Capability;
import org.osgi.framework.resource.Requirement;
import org.osgi.framework.resource.Resource;
+import org.osgi.service.repository.RepositoryContent;
-public class BundleResource implements Resource {
+public class BundleResource implements Resource, RepositoryContent {
public static BundleResource newInstance(URL content) throws IOException {
BundleResource result = new BundleResource(content);
result.capabilities.add(new OsgiIdentityCapability(result, result.manifest));
@@ -37,11 +38,13 @@ public class BundleResource implements R
}
private final List<Capability> capabilities = new ArrayList<Capability>();
+ private final URL content;
private final BundleManifest manifest;
private final List<Requirement> requirements = new ArrayList<Requirement>();
- private BundleResource(InputStream content) throws IOException {
- JarInputStream jis = new JarInputStream(content);
+ private BundleResource(URL content) throws IOException {
+ this.content = content;
+ JarInputStream jis = new JarInputStream(content.openStream());
try {
Manifest manifest = jis.getManifest();
if (manifest == null)
@@ -64,10 +67,6 @@ public class BundleResource implements R
}
}
- private BundleResource(URL content) throws IOException {
- this(content.openStream());
- }
-
private BundleResource(String content) throws IOException {
/*
* TODO
@@ -93,6 +92,11 @@ public class BundleResource implements R
}
return result;
}
+
+ @Override
+ public InputStream getContent() throws IOException {
+ return content.openStream();
+ }
public List<Requirement> getRequirements(String namespace) {
/* Requirements
Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemDirectoryResource.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemDirectoryResource.java?rev=1241900&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemDirectoryResource.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemDirectoryResource.java Wed Feb 8 13:54:41 2012
@@ -0,0 +1,66 @@
+package org.apache.aries.subsystem.core.resource;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.jar.Manifest;
+
+import org.apache.aries.subsystem.core.archive.SubsystemSymbolicNameHeader;
+import org.apache.aries.subsystem.core.internal.OsgiIdentityCapability;
+import org.apache.aries.util.filesystem.FileSystem;
+import org.apache.aries.util.filesystem.IDirectory;
+import org.apache.aries.util.manifest.ManifestProcessor;
+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.RepositoryContent;
+import org.osgi.service.subsystem.SubsystemConstants;
+
+public class SubsystemDirectoryResource implements Resource, RepositoryContent {
+ private final List<Capability> capabilities;
+ private final IDirectory directory;
+
+ public SubsystemDirectoryResource(File content) throws IOException {
+ this(FileSystem.getFSRoot(content));
+ }
+
+ public SubsystemDirectoryResource(IDirectory content) throws IOException {
+ if (!content.isDirectory())
+ throw new IllegalArgumentException("The content must represent a directory: " + content);
+ this.directory = content;
+ Manifest manifest = ManifestProcessor.obtainManifestFromAppDir(content, "OSGI-INF/DEPLOYMENT.MF");
+ if (manifest == null)
+ manifest = ManifestProcessor.obtainManifestFromAppDir(content, "OSGI-INF/SUBSYSTEM.MF");
+ String symbolicName = new SubsystemSymbolicNameHeader(manifest
+ .getMainAttributes().getValue(
+ SubsystemConstants.SUBSYSTEM_SYMBOLICNAME))
+ .getSymbolicName();
+ Version version = Version.parseVersion(manifest.getMainAttributes()
+ .getValue(SubsystemConstants.SUBSYSTEM_VERSION));
+ List<Capability> capabilities = new ArrayList<Capability>(1);
+ capabilities.add(new OsgiIdentityCapability(this, symbolicName, version, SubsystemConstants.IDENTITY_TYPE_SUBSYSTEM));
+ this.capabilities = Collections.unmodifiableList(capabilities);
+ }
+
+ @Override
+ public List<Capability> getCapabilities(String namespace) {
+ if (namespace == null || ResourceConstants.IDENTITY_NAMESPACE.equals(namespace))
+ return capabilities;
+ return Collections.emptyList();
+ }
+
+ @Override
+ public InputStream getContent() throws IOException {
+ return directory.open();
+ }
+
+ @Override
+ public List<Requirement> getRequirements(String namespace) {
+ return Collections.emptyList();
+ }
+}
Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemFileResource.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemFileResource.java?rev=1241900&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemFileResource.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemFileResource.java Wed Feb 8 13:54:41 2012
@@ -0,0 +1,88 @@
+package org.apache.aries.subsystem.core.resource;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.jar.Manifest;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.zip.ZipInputStream;
+
+import org.apache.aries.subsystem.core.archive.SubsystemSymbolicNameHeader;
+import org.apache.aries.subsystem.core.internal.OsgiIdentityCapability;
+import org.apache.aries.util.filesystem.FileSystem;
+import org.apache.aries.util.filesystem.IDirectory;
+import org.apache.aries.util.manifest.ManifestProcessor;
+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.RepositoryContent;
+import org.osgi.service.subsystem.SubsystemConstants;
+
+public class SubsystemFileResource implements Resource, RepositoryContent {
+ private static final String REGEX = "([^@])(?:@(.*))?.ssa";
+ private static final Pattern PATTERN = Pattern.compile(REGEX);
+
+ private final List<Capability> capabilities;
+ private final IDirectory directory;
+ private final File file;
+
+ public SubsystemFileResource(File content) throws IOException {
+ file = content;
+ directory = FileSystem.getFSRoot(content);
+ Manifest manifest = ManifestProcessor.obtainManifestFromAppDir(directory, "OSGI-INF/DEPLOYMENT.MF");
+ if (manifest == null)
+ manifest = ManifestProcessor.obtainManifestFromAppDir(directory, "OSGI-INF/SUBSYSTEM.MF");
+ String symbolicName = null;
+ Version version = Version.emptyVersion;
+ if (manifest != null) {
+ String value = manifest.getMainAttributes().getValue(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME);
+ if (value != null)
+ symbolicName = new SubsystemSymbolicNameHeader(value).getSymbolicName();
+ value = manifest.getMainAttributes().getValue(SubsystemConstants.SUBSYSTEM_VERSION);
+ if (value != null)
+ version = Version.parseVersion(value);
+ }
+ Matcher matcher = PATTERN.matcher(content.getName());;
+ if (symbolicName == null) {
+ if (!matcher.matches())
+ throw new IllegalArgumentException("No symbolic name");
+ symbolicName = new SubsystemSymbolicNameHeader(matcher.group(1)).getSymbolicName();
+ }
+ if (version == Version.emptyVersion && matcher.matches()) {
+ String group = matcher.group(2);
+ if (group != null)
+ version = Version.parseVersion(group);
+ }
+ List<Capability> capabilities = new ArrayList<Capability>(1);
+ capabilities.add(new OsgiIdentityCapability(this, symbolicName, version, SubsystemConstants.IDENTITY_TYPE_SUBSYSTEM));
+ this.capabilities = Collections.unmodifiableList(capabilities);
+ }
+
+ @Override
+ public List<Capability> getCapabilities(String namespace) {
+ if (namespace == null || ResourceConstants.IDENTITY_NAMESPACE.equals(namespace))
+ return capabilities;
+ return Collections.emptyList();
+ }
+
+ @Override
+ public InputStream getContent() throws IOException {
+ return new FileInputStream(file);
+ }
+
+ public String getLocation() {
+ return file.getAbsolutePath();
+ }
+
+ @Override
+ public List<Requirement> getRequirements(String namespace) {
+ return Collections.emptyList();
+ }
+}
Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemStreamResource.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemStreamResource.java?rev=1241900&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemStreamResource.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/resource/SubsystemStreamResource.java Wed Feb 8 13:54:41 2012
@@ -0,0 +1,94 @@
+package org.apache.aries.subsystem.core.resource;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.jar.Manifest;
+
+import org.apache.aries.subsystem.core.archive.SubsystemSymbolicNameHeader;
+import org.apache.aries.subsystem.core.internal.OsgiIdentityCapability;
+import org.apache.aries.subsystem.core.internal.SubsystemUri;
+import org.apache.aries.util.filesystem.FileSystem;
+import org.apache.aries.util.filesystem.ICloseableDirectory;
+import org.apache.aries.util.io.IOUtils;
+import org.apache.aries.util.manifest.ManifestProcessor;
+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.RepositoryContent;
+import org.osgi.service.subsystem.SubsystemConstants;
+
+public class SubsystemStreamResource implements Resource, RepositoryContent {
+ private final List<Capability> capabilities;
+ private final ICloseableDirectory directory;
+
+ public SubsystemStreamResource(String location, InputStream content) throws IOException, URISyntaxException {
+ SubsystemUri uri = null;
+ try {
+ if (location.startsWith("subsystem://"))
+ uri = new SubsystemUri(location);
+ if (content == null) {
+ if (uri != null)
+ content = uri.getURL().openStream();
+ else
+ content = new URL(location).openStream();
+ }
+ directory = FileSystem.getFSRoot(content);
+ if (directory == null)
+ throw new IOException("Unable to parse content of " + location);
+ }
+ finally {
+ IOUtils.close(content);
+ }
+ Manifest manifest = ManifestProcessor.obtainManifestFromAppDir(directory, "OSGI-INF/DEPLOYMENT.MF");
+ if (manifest == null)
+ manifest = ManifestProcessor.obtainManifestFromAppDir(directory, "OSGI-INF/SUBSYSTEM.MF");
+ String symbolicName = null;
+ Version version = Version.emptyVersion;
+ if (manifest != null) {
+ String value = manifest.getMainAttributes().getValue(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME);
+ if (value != null)
+ symbolicName = new SubsystemSymbolicNameHeader(value).getSymbolicName();
+ value = manifest.getMainAttributes().getValue(SubsystemConstants.SUBSYSTEM_VERSION);
+ if (value != null)
+ version = Version.parseVersion(value);
+ }
+ if (symbolicName == null) {
+ if (uri == null)
+ throw new IllegalArgumentException("No symbolic name");
+ symbolicName = uri.getSymbolicName();
+ }
+ if (version == Version.emptyVersion && uri != null)
+ version = uri.getVersion();
+ List<Capability> capabilities = new ArrayList<Capability>(1);
+ capabilities.add(new OsgiIdentityCapability(this, symbolicName, version, SubsystemConstants.IDENTITY_TYPE_SUBSYSTEM));
+ this.capabilities = Collections.unmodifiableList(capabilities);
+ }
+
+ public void close() {
+ IOUtils.close(directory);
+ }
+
+ @Override
+ public List<Capability> getCapabilities(String namespace) {
+ if (namespace == null || ResourceConstants.IDENTITY_NAMESPACE.equals(namespace))
+ return capabilities;
+ return Collections.emptyList();
+ }
+
+ @Override
+ public InputStream getContent() throws IOException {
+ return directory.open();
+ }
+
+ @Override
+ public List<Requirement> getRequirements(String namespace) {
+ return Collections.emptyList();
+ }
+}
Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/felix/resolver/FelixCapability.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/felix/resolver/FelixCapability.java?rev=1241900&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/felix/resolver/FelixCapability.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/felix/resolver/FelixCapability.java Wed Feb 8 13:54:41 2012
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.resolver;
+
+import java.util.List;
+
+public interface FelixCapability
+{
+ List<String> getUses();
+}
Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/felix/resolver/FelixEnvironment.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/felix/resolver/FelixEnvironment.java?rev=1241900&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/felix/resolver/FelixEnvironment.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/felix/resolver/FelixEnvironment.java Wed Feb 8 13:54:41 2012
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.resolver;
+
+import org.osgi.framework.resource.Resource;
+import org.osgi.service.resolver.Environment;
+import org.osgi.service.resolver.ResolutionException;
+
+public interface FelixEnvironment extends Environment
+{
+ void checkExecutionEnvironment(Resource resource) throws ResolutionException;
+ void checkNativeLibraries(Resource resource) throws ResolutionException;
+}
\ No newline at end of file
Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/felix/resolver/FelixResolver.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/felix/resolver/FelixResolver.java?rev=1241900&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/felix/resolver/FelixResolver.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/felix/resolver/FelixResolver.java Wed Feb 8 13:54:41 2012
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.resolver;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedSet;
+import org.osgi.framework.resource.Capability;
+import org.osgi.framework.resource.Requirement;
+import org.osgi.framework.resource.Resource;
+import org.osgi.framework.resource.Wire;
+import org.osgi.service.resolver.Resolver;
+
+public interface FelixResolver extends Resolver
+{
+ Map<Resource, List<Wire>> resolve(
+ FelixEnvironment env,
+ Collection<? extends Resource> mandatoryRevisions,
+ Collection<? extends Resource> optionalRevisions,
+ Collection<? extends Resource> ondemandFragments);
+ Map<Resource, List<Wire>> resolve(
+ FelixEnvironment env,
+ Resource resource,
+ Requirement dynReq,
+ SortedSet<Capability> cands,
+ Collection<? extends Resource> ondemandFragments);
+}
\ No newline at end of file
Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/felix/resolver/Logger.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/felix/resolver/Logger.java?rev=1241900&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/felix/resolver/Logger.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/felix/resolver/Logger.java Wed Feb 8 13:54:41 2012
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.resolver;
+
+public interface Logger
+{
+ static final int LOG_ERROR = 1;
+ static final int LOG_WARNING = 2;
+ static final int LOG_INFO = 3;
+ static final int LOG_DEBUG = 4;
+
+ void log(int level, String msg);
+
+ void log(int level, String msg, Throwable throwable);
+}
\ No newline at end of file
Added: aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/felix/resolver/impl/Activator.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/felix/resolver/impl/Activator.java?rev=1241900&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/felix/resolver/impl/Activator.java (added)
+++ aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/felix/resolver/impl/Activator.java Wed Feb 8 13:54:41 2012
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.resolver.impl;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class Activator implements BundleActivator
+{
+ public void start(BundleContext bc) throws Exception
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
+ public void stop(BundleContext bc) throws Exception
+ {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+}
\ No newline at end of file