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/04/09 17:28:01 UTC

svn commit: r1311281 - in /aries/trunk/subsystem: subsystem-core/ subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/ subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/ subsystem-itests/src/test/java/org/apache/aries/...

Author: jwross
Date: Mon Apr  9 15:28:00 2012
New Revision: 1311281

URL: http://svn.apache.org/viewvc?rev=1311281&view=rev
Log:
ARIES-825: Update subsystems to latest Subsystem, Resolver, and Repository APIs.

Removed dependency on felix bundle repository from core. It's only needed in itests.

Added:
    aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/
    aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/
    aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/FelixCapabilityAdapter.java
    aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/FelixProperty.java
    aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/FelixRepositoryAdapter.java
    aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/FelixRequirementAdapter.java
    aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/FelixResourceAdapter.java
    aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/OsgiCapabilityAdapter.java
    aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/OsgiRequirementAdapter.java
    aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/OsgiResourceAdapter.java
    aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/RepositoryAdminRepository.java
Removed:
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/SubsystemResolver.java
    aries/trunk/subsystem/subsystem-core/src/main/java/org/apache/aries/subsystem/core/obr/felix/
Modified:
    aries/trunk/subsystem/subsystem-core/pom.xml
    aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java
    aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/RepositoryGenerator.java

Modified: aries/trunk/subsystem/subsystem-core/pom.xml
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-core/pom.xml?rev=1311281&r1=1311280&r2=1311281&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-core/pom.xml (original)
+++ aries/trunk/subsystem/subsystem-core/pom.xml Mon Apr  9 15:28:00 2012
@@ -120,17 +120,6 @@
             <version>3.8.0-SNAPSHOT</version>
         </dependency>
         <dependency>
-            <groupId>org.apache.felix</groupId>
-            <artifactId>org.apache.felix.bundlerepository</artifactId>
-            <version>1.6.4</version>
-            <exclusions>
-            	<exclusion>
-            		<groupId>org.osgi</groupId>
-            		<artifactId>org.osgi.core</artifactId>
-            	</exclusion>
-            </exclusions>
-        </dependency>
-        <dependency>
             <groupId>org.apache.aries.testsupport</groupId>
             <artifactId>org.apache.aries.testsupport.unit</artifactId>
             <version>0.5-SNAPSHOT</version>

Modified: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java?rev=1311281&r1=1311280&r2=1311281&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java (original)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/SubsystemTest.java Mon Apr  9 15:28:00 2012
@@ -43,8 +43,8 @@ import org.apache.aries.subsystem.core.R
 import org.apache.aries.subsystem.core.archive.ProvisionPolicyDirective;
 import org.apache.aries.subsystem.core.archive.SubsystemTypeHeader;
 import org.apache.aries.subsystem.core.internal.SubsystemIdentifier;
-import org.apache.aries.subsystem.core.obr.felix.RepositoryAdminRepository;
 import org.apache.aries.subsystem.core.resource.BundleResource;
+import org.apache.aries.subsystem.itests.obr.felix.RepositoryAdminRepository;
 import org.apache.aries.subsystem.itests.util.RepositoryGenerator;
 import org.apache.aries.subsystem.itests.util.TestRepository;
 import org.apache.aries.subsystem.itests.util.Utils;

Added: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/FelixCapabilityAdapter.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/FelixCapabilityAdapter.java?rev=1311281&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/FelixCapabilityAdapter.java (added)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/FelixCapabilityAdapter.java Mon Apr  9 15:28:00 2012
@@ -0,0 +1,58 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.aries.subsystem.itests.obr.felix;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.aries.subsystem.core.resource.AbstractCapability;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.resource.Resource;
+
+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");
+		this.capability = capability;
+		this.resource = resource;
+	}
+
+	public Map<String, Object> getAttributes() {
+		Map<String, Object> result = capability.getPropertiesAsMap();
+		result.put(getNamespace(), result.get(capability.getName()));
+		return result;
+	}
+
+	public Map<String, String> getDirectives() {
+		return Collections.emptyMap();
+	}
+
+	public String getNamespace() {
+		String namespace = capability.getName();
+		if (namespace.equals(org.apache.felix.bundlerepository.Capability.BUNDLE))
+			return BundleRevision.BUNDLE_NAMESPACE;
+		if (namespace.equals(org.apache.felix.bundlerepository.Capability.FRAGMENT))
+			return BundleRevision.HOST_NAMESPACE;
+		if (namespace.equals(org.apache.felix.bundlerepository.Capability.PACKAGE))
+			return BundleRevision.PACKAGE_NAMESPACE;
+		return namespace;
+	}
+
+	public Resource getResource() {
+		return resource;
+	}
+}

Added: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/FelixProperty.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/FelixProperty.java?rev=1311281&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/FelixProperty.java (added)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/FelixProperty.java Mon Apr  9 15:28:00 2012
@@ -0,0 +1,71 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.aries.subsystem.itests.obr.felix;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.felix.bundlerepository.Property;
+import org.osgi.framework.Version;
+
+public class FelixProperty implements Property {
+	private static Set<?> asSet(List<?> list) {
+		return new HashSet<Object>(list);
+	}
+	
+	private final String name;
+	private final Object value;
+	
+	public FelixProperty(String name, Object value) {
+		if (name == null)
+			throw new NullPointerException("Missing required parameter: name");
+		if (value == null)
+			throw new NullPointerException("Missing required parameter: value");
+		this.name = name;
+		this.value = value;
+	}
+	
+	public FelixProperty(Map.Entry<String, Object> entry) {
+		this(entry.getKey(), entry.getValue());
+	}
+
+	public Object getConvertedValue() {
+		if (value instanceof List)
+			return asSet((List<?>)value);
+		return value;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public String getType() {
+		if (value instanceof Version)
+			return Property.VERSION;
+		if (value instanceof Long)
+			return Property.LONG;
+		if (value instanceof Double)
+			return Property.DOUBLE;
+		if (value instanceof List<?>)
+			return Property.SET;
+		return null;
+	}
+
+	public String getValue() {
+		return String.valueOf(value);
+	}
+
+}

Added: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/FelixRepositoryAdapter.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/FelixRepositoryAdapter.java?rev=1311281&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/FelixRepositoryAdapter.java (added)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/FelixRepositoryAdapter.java Mon Apr  9 15:28:00 2012
@@ -0,0 +1,153 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.aries.subsystem.itests.obr.felix;
+
+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.namespace.IdentityNamespace;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+import org.osgi.service.repository.Repository;
+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;
+	}
+	
+	public Collection<Capability> findProviders(Requirement requirement) {
+		logger.debug(LOG_ENTRY, "findProviders", requirement);
+		update();
+		List<Capability> result = Collections.emptyList();
+		if (IdentityNamespace.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();
+			}
+		}
+		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 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?
+									IdentityNamespace.TYPE_BUNDLE);
+						logger.debug("Indexing capability {}", capability);
+						capabilities.add(capability);
+					}
+				}
+			}
+		}
+		logger.debug(LOG_EXIT, "update");
+	}
+}

Added: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/FelixRequirementAdapter.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/FelixRequirementAdapter.java?rev=1311281&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/FelixRequirementAdapter.java (added)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/FelixRequirementAdapter.java Mon Apr  9 15:28:00 2012
@@ -0,0 +1,73 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.aries.subsystem.itests.obr.felix;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.osgi.framework.Constants;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+
+public class FelixRequirementAdapter implements Requirement {
+	private final org.apache.felix.bundlerepository.Requirement requirement;
+	private final Resource resource;
+	
+	public FelixRequirementAdapter(org.apache.felix.bundlerepository.Requirement requirement, Resource resource) {
+		if (requirement == null)
+			throw new NullPointerException("Missing required parameter: requirement");
+		if (resource == null)
+			throw new NullPointerException("Missing required parameter: resource");
+		this.requirement = requirement;
+		this.resource = resource;
+	}
+
+	public Map<String, Object> getAttributes() {
+		return Collections.emptyMap();
+	}
+
+	public Map<String, String> getDirectives() {
+		Map<String, String> result = new HashMap<String, String>(1);
+		/* (1) The Felix OBR specific "mandatory:<*" syntax must be stripped out of the filter.
+		 * (2) The namespace must be translated.
+		 */
+		result.put(Constants.FILTER_DIRECTIVE, requirement.getFilter()
+				.replaceAll("\\(mandatory\\:\\<\\*[^\\)]*\\)", "")
+				.replaceAll(requirement.getName() + '=', getNamespace() + '='));
+		return result;
+	}
+
+	public String getNamespace() {
+		String namespace = requirement.getName();
+		if (namespace.equals(org.apache.felix.bundlerepository.Capability.BUNDLE))
+			return BundleRevision.BUNDLE_NAMESPACE;
+		if (namespace.equals(org.apache.felix.bundlerepository.Capability.FRAGMENT))
+			return BundleRevision.HOST_NAMESPACE;
+		if (namespace.equals(org.apache.felix.bundlerepository.Capability.PACKAGE))
+			return BundleRevision.PACKAGE_NAMESPACE;
+		return namespace;
+	}
+
+	public Resource getResource() {
+		return resource;
+	}
+
+	public boolean matches(Capability capability) {
+		return requirement.isSatisfied(new OsgiCapabilityAdapter(capability));
+	}
+
+}

Added: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/FelixResourceAdapter.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/FelixResourceAdapter.java?rev=1311281&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/FelixResourceAdapter.java (added)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/FelixResourceAdapter.java Mon Apr  9 15:28:00 2012
@@ -0,0 +1,119 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.aries.subsystem.itests.obr.felix;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.aries.subsystem.core.ResourceHelper;
+import org.apache.aries.subsystem.core.internal.OsgiContentCapability;
+import org.apache.aries.subsystem.core.internal.OsgiIdentityCapability;
+import org.osgi.framework.namespace.IdentityNamespace;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+import org.osgi.service.repository.RepositoryContent;
+
+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;
+		if (BundleRevision.HOST_NAMESPACE.equals(namespace))
+			return org.apache.felix.bundlerepository.Capability.FRAGMENT;
+		if (BundleRevision.PACKAGE_NAMESPACE.equals(namespace))
+			return org.apache.felix.bundlerepository.Capability.PACKAGE;
+		return namespace;
+	}
+	
+	private final org.apache.felix.bundlerepository.Resource resource;
+	
+	public FelixResourceAdapter(final org.apache.felix.bundlerepository.Resource resource) {
+		this.resource = resource;
+	}
+	
+	public boolean equals(Object o) {
+		if (o == this) 
+			return true;
+		if (!(o instanceof Resource)) 
+			return false;
+		Resource that = (Resource)o;
+		if (!ResourceHelper.getTypeAttribute(that).equals(ResourceHelper.getTypeAttribute(this))) 
+			return false;
+		if (!ResourceHelper.getSymbolicNameAttribute(that).equals(ResourceHelper.getSymbolicNameAttribute(this)))
+			return false;
+		if (!ResourceHelper.getVersionAttribute(that).equals(ResourceHelper.getVersionAttribute(this)))
+			return false;
+		return true;
+	}
+	
+	public int hashCode() {
+		int result = 17;
+		result = 31 * result + ResourceHelper.getTypeAttribute(this).hashCode();
+		result = 31 * result + ResourceHelper.getSymbolicNameAttribute(this).hashCode();
+		result = 31 * result + ResourceHelper.getVersionAttribute(this).hashCode();
+		return result;
+	}
+	
+	public List<Capability> getCapabilities(String namespace) {
+		namespace = toFelixNamespace(namespace);
+		org.apache.felix.bundlerepository.Capability[] capabilities = resource.getCapabilities();
+		ArrayList<Capability> result = new ArrayList<Capability>(capabilities.length);
+		if (namespace == null || namespace.equals(IdentityNamespace.IDENTITY_NAMESPACE)) {
+			result.add(
+					// TODO Assuming these are all of type osgi.bundle.
+					new OsgiIdentityCapability(
+							this,
+							resource.getSymbolicName(),
+							resource.getVersion()));
+		}
+		// TODO Add to constants.
+		if (namespace == null || namespace.equals("osgi.content")) {
+			result.add(
+					new OsgiContentCapability(
+							this,
+							resource.getURI()));
+		}
+		for (org.apache.felix.bundlerepository.Capability capability : capabilities) {
+			if (namespace != null && !capability.getName().equals(namespace)) continue;
+			result.add(new FelixCapabilityAdapter(capability, this));
+		}
+		result.trimToSize();
+		return result;
+	}
+	
+	@Override
+	public InputStream getContent() {
+		try {
+			return new URL(resource.getURI()).openStream();
+		}
+		catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	public List<Requirement> getRequirements(String namespace) {
+		namespace = toFelixNamespace(namespace);
+		org.apache.felix.bundlerepository.Requirement[] requirements = resource.getRequirements();
+		ArrayList<Requirement> result = new ArrayList<Requirement>(requirements.length);
+		for (final org.apache.felix.bundlerepository.Requirement requirement : requirements) {
+			if (namespace == null || requirement.getName().equals(namespace)) 
+				result.add(new FelixRequirementAdapter(requirement, this));
+		}
+		result.trimToSize();
+		return result;
+	}
+}

Added: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/OsgiCapabilityAdapter.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/OsgiCapabilityAdapter.java?rev=1311281&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/OsgiCapabilityAdapter.java (added)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/OsgiCapabilityAdapter.java Mon Apr  9 15:28:00 2012
@@ -0,0 +1,74 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.aries.subsystem.itests.obr.felix;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.felix.bundlerepository.Capability;
+import org.apache.felix.bundlerepository.Property;
+import org.osgi.framework.wiring.BundleRevision;
+
+public class OsgiCapabilityAdapter implements Capability {
+	private final org.osgi.resource.Capability capability;
+	
+	public OsgiCapabilityAdapter(org.osgi.resource.Capability capability) {
+		if (capability == null)
+			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();
+		if (namespace.equals(BundleRevision.BUNDLE_NAMESPACE))
+			return Capability.BUNDLE;
+		if (namespace.equals(BundleRevision.HOST_NAMESPACE))
+			return Capability.FRAGMENT;
+		if (namespace.equals(BundleRevision.PACKAGE_NAMESPACE))
+			return Capability.PACKAGE;
+		return namespace;
+	}
+
+	public Property[] getProperties() {
+		Map<String, Object> attributes = capability.getAttributes();
+		Collection<Property> result = new ArrayList<Property>(attributes.size());
+		for (final Map.Entry<String, Object> entry : capability.getAttributes().entrySet()) {
+			if (entry.getKey().equals(capability.getNamespace())) {
+				result.add(new FelixProperty(getName(), entry.getValue()));
+				continue;
+			}
+			result.add(new FelixProperty(entry));
+		}
+		return result.toArray(new Property[result.size()]);
+	}
+
+	@SuppressWarnings("rawtypes")
+	public Map getPropertiesAsMap() {
+		Map<String, Object> result = new HashMap<String, Object>(capability.getAttributes());
+		result.put(getName(), result.get(capability.getNamespace()));
+		return result;
+	}
+	
+	@Override
+	public int hashCode() {
+		return capability.hashCode();
+	}
+}

Added: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/OsgiRequirementAdapter.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/OsgiRequirementAdapter.java?rev=1311281&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/OsgiRequirementAdapter.java (added)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/OsgiRequirementAdapter.java Mon Apr  9 15:28:00 2012
@@ -0,0 +1,77 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.aries.subsystem.itests.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.resource.Requirement requirement;
+	
+	public OsgiRequirementAdapter(org.osgi.resource.Requirement requirement) {
+		if (requirement == null)
+			throw new NullPointerException("Missing required parameter: requirement");
+		this.requirement = requirement;
+	}
+
+	public String getComment() {
+		return null;
+	}
+
+	public String getFilter() {
+		return requirement.getDirectives().get(Constants.FILTER_DIRECTIVE);
+	}
+
+	public String getName() {
+		String namespace = requirement.getNamespace();
+		if (namespace.equals(BundleRevision.BUNDLE_NAMESPACE))
+			return Capability.BUNDLE;
+		if (namespace.equals(BundleRevision.HOST_NAMESPACE))
+			return Capability.FRAGMENT;
+		if (namespace.equals(BundleRevision.PACKAGE_NAMESPACE))
+			return Capability.PACKAGE;
+		return namespace;
+	}
+
+	public boolean isExtend() {
+		return false;
+	}
+
+	public boolean isMultiple() {
+		return false;
+	}
+
+	public boolean isOptional() {
+		String resolution = requirement.getDirectives().get(Constants.RESOLUTION_DIRECTIVE);
+		return Constants.RESOLUTION_OPTIONAL.equals(resolution);
+	}
+
+	public boolean isSatisfied(Capability capability) {
+		logger.debug(LOG_ENTRY, "isSatisfied", capability);
+		boolean result = ResourceHelper.matches(requirement, new FelixCapabilityAdapter(capability, null));
+		logger.debug(LOG_EXIT, "isSatisfied", result);
+		return result;
+	}
+
+}

Added: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/OsgiResourceAdapter.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/OsgiResourceAdapter.java?rev=1311281&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/OsgiResourceAdapter.java (added)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/OsgiResourceAdapter.java Mon Apr  9 15:28:00 2012
@@ -0,0 +1,90 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.aries.subsystem.itests.obr.felix;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.aries.subsystem.core.ResourceHelper;
+import org.apache.felix.bundlerepository.Capability;
+import org.apache.felix.bundlerepository.Requirement;
+import org.apache.felix.bundlerepository.Resource;
+import org.osgi.framework.Version;
+
+// TODO Need to distinguish between resources that have already been deployed (local) and those that have not.
+public class OsgiResourceAdapter implements Resource {
+	private final org.osgi.resource.Resource resource;
+	
+	public OsgiResourceAdapter(org.osgi.resource.Resource resource) {
+		if (resource == null)
+			throw new NullPointerException("Missing required parameter: resource");
+		this.resource = resource;
+	}
+
+	public Capability[] getCapabilities() {
+		Collection<org.osgi.resource.Capability> capabilities = resource.getCapabilities(null);
+		Collection<Capability> result = new ArrayList<Capability>(capabilities.size());
+		for (org.osgi.resource.Capability capability : capabilities)
+			result.add(new OsgiCapabilityAdapter(capability));
+		return result.toArray(new Capability[result.size()]);
+	}
+
+	public String[] getCategories() {
+		return new String[0];
+	}
+
+	public String getId() {
+		String symbolicName = ResourceHelper.getSymbolicNameAttribute(resource);
+		Version version = ResourceHelper.getVersionAttribute(resource);
+		return symbolicName + ";version=" + version;
+	}
+
+	public String getPresentationName() {
+		return ResourceHelper.getSymbolicNameAttribute(resource);
+	}
+
+	public Map getProperties() {
+		return Collections.emptyMap();
+	}
+
+	public Requirement[] getRequirements() {
+		Collection<org.osgi.resource.Requirement> requirements = resource.getRequirements(null);
+		Collection<Requirement> result = new ArrayList<Requirement>(requirements.size());
+		for (org.osgi.resource.Requirement requirement : requirements)
+			result.add(new OsgiRequirementAdapter(requirement));
+		return result.toArray(new Requirement[result.size()]);
+	}
+
+	public Long getSize() {
+		return -1L;
+	}
+
+	public String getSymbolicName() {
+		return ResourceHelper.getSymbolicNameAttribute(resource);
+	}
+
+	public String getURI() {
+		return ResourceHelper.getContentAttribute(resource);
+	}
+
+	public Version getVersion() {
+		return ResourceHelper.getVersionAttribute(resource);
+	}
+
+	public boolean isLocal() {
+		return false;
+	}
+}

Added: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/RepositoryAdminRepository.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/RepositoryAdminRepository.java?rev=1311281&view=auto
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/RepositoryAdminRepository.java (added)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/obr/felix/RepositoryAdminRepository.java Mon Apr  9 15:28:00 2012
@@ -0,0 +1,95 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.aries.subsystem.itests.obr.felix;
+
+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.Arrays;
+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.namespace.IdentityNamespace;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+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;
+	}
+	
+	public Collection<Capability> findProviders(Requirement requirement) {
+		logger.debug(LOG_ENTRY, "findProviders", requirement);
+		Collection<Capability> result = Collections.emptyList();
+		if (IdentityNamespace.IDENTITY_NAMESPACE.equals(requirement.getNamespace())) {
+			result = new ArrayList<Capability>();
+			for (Repository repository : repositories) {
+				Map<Requirement, Collection<Capability>> map = repository.findProviders(Arrays.asList(requirement));
+				Collection<Capability> capabilities = map.get(requirement);
+				if (capabilities != null)
+					result.addAll(capabilities);
+			}
+			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 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;
+	}
+}

Modified: aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/RepositoryGenerator.java
URL: http://svn.apache.org/viewvc/aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/RepositoryGenerator.java?rev=1311281&r1=1311280&r2=1311281&view=diff
==============================================================================
--- aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/RepositoryGenerator.java (original)
+++ aries/trunk/subsystem/subsystem-itests/src/test/java/org/apache/aries/subsystem/itests/util/RepositoryGenerator.java Mon Apr  9 15:28:00 2012
@@ -31,8 +31,8 @@ import javax.xml.transform.stream.Stream
 import org.apache.aries.application.Content;
 import org.apache.aries.application.management.BundleInfo;
 import org.apache.aries.subsystem.core.ResourceHelper;
-import org.apache.aries.subsystem.core.obr.felix.FelixResourceAdapter;
-import org.apache.aries.subsystem.core.obr.felix.OsgiResourceAdapter;
+import org.apache.aries.subsystem.itests.obr.felix.FelixResourceAdapter;
+import org.apache.aries.subsystem.itests.obr.felix.OsgiResourceAdapter;
 import org.apache.felix.bundlerepository.Capability;
 import org.apache.felix.bundlerepository.Property;
 import org.apache.felix.bundlerepository.Reason;