Author: davidb Date: Mon Feb 3 15:22:25 2014 New Revision: 1563948 URL: http://svn.apache.org/r1563948 Log: [FELIX-4370] Support for RepositoryContent interface
Added test and also some other refactoring/improvements. Modified: felix/trunk/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/FelixCapabilityAdapter.java felix/trunk/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/FelixResourceAdapter.java felix/trunk/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/OSGiRepositoryImpl.java felix/trunk/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/OSGiRepositoryImplTest.java Modified: felix/trunk/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/FelixCapabilityAdapter.java URL: http://svn.apache.org/viewvc/felix/trunk/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/FelixCapabilityAdapter.java?rev=1563948&r1=1563947&r2=1563948&view=diff ============================================================================== --- felix/trunk/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/FelixCapabilityAdapter.java (original) +++ felix/trunk/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/FelixCapabilityAdapter.java Mon Feb 3 15:22:25 2014 @@ -14,9 +14,9 @@ package org.apache.felix.bundlerepository.impl; import java.util.Collections; +import java.util.HashMap; import java.util.Map; -import org.osgi.framework.namespace.BundleNamespace; import org.osgi.resource.Capability; import org.osgi.resource.Resource; @@ -24,6 +24,7 @@ public class FelixCapabilityAdapter impl { private final org.apache.felix.bundlerepository.Capability capability; private final Resource resource; + private volatile Map<String, Object> convertedAttributes; public FelixCapabilityAdapter(org.apache.felix.bundlerepository.Capability capability, Resource resource) { @@ -35,22 +36,18 @@ public class FelixCapabilityAdapter impl public Map<String, Object> getAttributes() { - Map<String, Object> result = capability.getPropertiesAsMap(); - String namespace = getNamespace(); - if (BundleNamespace.BUNDLE_NAMESPACE.equals(namespace)) - result.put(BundleNamespace.BUNDLE_NAMESPACE, result.get(org.apache.felix.bundlerepository.Resource.SYMBOLIC_NAME)); - - /* - This was here, but I don't think it applies in this use-case. - if (ServiceNamespace.SERVICE_NAMESPACE.equals(namespace)) - result.put(ServiceNamespace.CAPABILITY_OBJECTCLASS_ATTRIBUTE, - result.get(ServiceNamespace.CAPABILITY_OBJECTCLASS_ATTRIBUTE.toLowerCase())); - else if (BundleNamespace.BUNDLE_NAMESPACE.equals(namespace)) - result.put(BundleNamespace.BUNDLE_NAMESPACE, result.get(org.apache.felix.bundlerepository.Resource.SYMBOLIC_NAME)); - else - result.put(namespace, result.get(capability.getName())); - */ - return result; + if (convertedAttributes == null) + { + Map<String, Object> orgMap = capability.getPropertiesAsMap(); + HashMap<String, Object> converted = new HashMap<String, Object>(orgMap.size()); + + for (Map.Entry<String, Object> entry : orgMap.entrySet()) + { + converted.put(NamespaceTranslator.getOSGiNamespace(entry.getKey()), entry.getValue()); + } + convertedAttributes = converted; // Cache the result + } + return convertedAttributes; } public Map<String, String> getDirectives() Modified: felix/trunk/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/FelixResourceAdapter.java URL: http://svn.apache.org/viewvc/felix/trunk/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/FelixResourceAdapter.java?rev=1563948&r1=1563947&r2=1563948&view=diff ============================================================================== --- felix/trunk/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/FelixResourceAdapter.java (original) +++ felix/trunk/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/FelixResourceAdapter.java Mon Feb 3 15:22:25 2014 @@ -17,13 +17,9 @@ import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.Callable; -import org.apache.felix.bundlerepository.impl.LazyHashMap.LazyValue; -import org.osgi.framework.Version; import org.osgi.framework.namespace.IdentityNamespace; import org.osgi.resource.Capability; import org.osgi.resource.Requirement; @@ -44,13 +40,19 @@ public class FelixResourceAdapter implem { if (namespace == null || namespace.equals(IdentityNamespace.IDENTITY_NAMESPACE)) { - Capability c = newOsgiIdentityCapability(this, resource.getSymbolicName(), resource.getVersion()); - return Collections.singletonList(c); + // TODO cater for null request + Object type = resource.getProperties().get(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE); + OSGiCapabilityImpl c = OSGiRepositoryImpl.newOSGiIdentityCapability(resource.getSymbolicName(), + type != null ? type.toString() : IdentityNamespace.TYPE_BUNDLE, resource.getVersion()); + c.setResource(this); + return Collections.<Capability>singletonList(c); } if (namespace.equals(ContentNamespace.CONTENT_NAMESPACE)) { - Capability c = newOsgiContentCapability(this, resource.getURI(), resource.getSize()); - return Collections.singletonList(c); + // TODO cater for null request + OSGiCapabilityImpl c = OSGiRepositoryImpl.newOSGiContentCapability(resource.getURI(), resource.getSize()); + c.setResource(this); + return Collections.<Capability>singletonList(c); } namespace = NamespaceTranslator.getFelixNamespace(namespace); @@ -66,40 +68,13 @@ public class FelixResourceAdapter implem return result; } - private static Capability newOsgiIdentityCapability(Resource res, String symbolicName, Version version) - { - Map<String, Object> idAttrs = new HashMap<String, Object>(); - idAttrs.put(IdentityNamespace.IDENTITY_NAMESPACE, symbolicName); - idAttrs.put(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE, IdentityNamespace.TYPE_BUNDLE); - idAttrs.put(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE, version); - - return new OSGiCapabilityImpl(IdentityNamespace.IDENTITY_NAMESPACE, idAttrs, Collections.<String, String> emptyMap(), res); - } - - private static Capability newOsgiContentCapability(Resource res, final String uri, long size) - { - // TODO duplicated in OSGiRepositoryImpl - LazyValue<String, Object> lazyValue = - new LazyValue<String, Object>(ContentNamespace.CONTENT_NAMESPACE, new Callable<Object>() { - public Object call() throws Exception - { - // This is expensive to do, so only compute it when actually obtained... - return OSGiRepositoryImpl.getSHA256(uri); - } - }); - Map<String, Object> contentAttrs = new LazyHashMap<String, Object>(Collections.singleton(lazyValue)); - contentAttrs.put(ContentNamespace.CAPABILITY_MIME_ATTRIBUTE, "application/vnd.osgi.bundle"); - contentAttrs.put(ContentNamespace.CAPABILITY_SIZE_ATTRIBUTE, size); - contentAttrs.put(ContentNamespace.CAPABILITY_URL_ATTRIBUTE, uri); - return new OSGiCapabilityImpl(ContentNamespace.CONTENT_NAMESPACE, contentAttrs, Collections.<String, String> emptyMap()); - } - public InputStream getContent() { try { return new URL(resource.getURI()).openStream(); - } catch (Exception e) + } + catch (Exception e) { throw new RuntimeException(e); } Modified: felix/trunk/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/OSGiRepositoryImpl.java URL: http://svn.apache.org/viewvc/felix/trunk/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/OSGiRepositoryImpl.java?rev=1563948&r1=1563947&r2=1563948&view=diff ============================================================================== --- felix/trunk/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/OSGiRepositoryImpl.java (original) +++ felix/trunk/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/OSGiRepositoryImpl.java Mon Feb 3 15:22:25 2014 @@ -37,6 +37,7 @@ import org.apache.felix.bundlerepository import org.apache.felix.bundlerepository.impl.LazyHashMap.LazyValue; import org.osgi.framework.Filter; import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.Version; import org.osgi.framework.namespace.IdentityNamespace; import org.osgi.resource.Capability; import org.osgi.resource.Namespace; @@ -107,37 +108,16 @@ public class OSGiRepositoryImpl implemen private void addResourceForIdentity(final org.apache.felix.bundlerepository.Resource res, Filter filter, List<Capability> caps) throws Exception { - Map<String, Object> idAttrs = new HashMap<String, Object>(); - idAttrs.put(IdentityNamespace.IDENTITY_NAMESPACE, res.getSymbolicName()); Object type = res.getProperties().get(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE); - idAttrs.put(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE, - type != null ? type.toString() : IdentityNamespace.TYPE_BUNDLE); - idAttrs.put(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE, res.getVersion()); - + OSGiCapabilityImpl idCap = newOSGiIdentityCapability(res.getSymbolicName(), + type != null ? type.toString() : IdentityNamespace.TYPE_BUNDLE, res.getVersion()); if (filter != null) { - if (!filter.matches(idAttrs)) + if (!filter.matches(idCap.getAttributes())) return; } - OSGiCapabilityImpl idCap = new OSGiCapabilityImpl(IdentityNamespace.IDENTITY_NAMESPACE, idAttrs, - Collections.<String, String>emptyMap()); - - LazyValue<String, Object> lazyValue = new LazyHashMap.LazyValue<String, Object>(ContentNamespace.CONTENT_NAMESPACE, - new Callable<Object>() - { - public Object call() throws Exception - { - // This is expensive to compute, so only do it if we need it... - return getSHA256(res.getURI()); - } - }); - Map<String, Object> contentAttrs = new LazyHashMap<String, Object>(Collections.singleton(lazyValue)); - contentAttrs.put(ContentNamespace.CAPABILITY_MIME_ATTRIBUTE, "application/vnd.osgi.bundle"); - contentAttrs.put(ContentNamespace.CAPABILITY_SIZE_ATTRIBUTE, res.getSize()); - contentAttrs.put(ContentNamespace.CAPABILITY_URL_ATTRIBUTE, res.getURI()); - OSGiCapabilityImpl contentCap = new OSGiCapabilityImpl(ContentNamespace.CONTENT_NAMESPACE, contentAttrs, - Collections.<String, String>emptyMap()); + OSGiCapabilityImpl contentCap = newOSGiContentCapability(res.getURI(), res.getSize()); List<OSGiCapabilityImpl> capabilities = Arrays.<OSGiCapabilityImpl>asList(idCap, contentCap); Resource resource = @@ -151,6 +131,33 @@ public class OSGiRepositoryImpl implemen caps.add(idCap); } + static OSGiCapabilityImpl newOSGiIdentityCapability(String symbolicName, String type, Version version) + { + Map<String, Object> idAttrs = new HashMap<String, Object>(); + idAttrs.put(IdentityNamespace.IDENTITY_NAMESPACE, symbolicName); + idAttrs.put(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE, type); + idAttrs.put(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE, version); + + return new OSGiCapabilityImpl(IdentityNamespace.IDENTITY_NAMESPACE, idAttrs, Collections.<String, String> emptyMap()); + } + + static OSGiCapabilityImpl newOSGiContentCapability(final String uri, long size) + { + LazyValue<String, Object> lazyValue = + new LazyValue<String, Object>(ContentNamespace.CONTENT_NAMESPACE, new Callable<Object>() { + public Object call() throws Exception + { + // This is expensive to do, so only compute it when actually obtained... + return OSGiRepositoryImpl.getSHA256(uri); + } + }); + Map<String, Object> contentAttrs = new LazyHashMap<String, Object>(Collections.singleton(lazyValue)); + contentAttrs.put(ContentNamespace.CAPABILITY_MIME_ATTRIBUTE, "application/vnd.osgi.bundle"); // TODO support other types + contentAttrs.put(ContentNamespace.CAPABILITY_SIZE_ATTRIBUTE, size); + contentAttrs.put(ContentNamespace.CAPABILITY_URL_ATTRIBUTE, uri); + return new OSGiCapabilityImpl(ContentNamespace.CONTENT_NAMESPACE, contentAttrs, Collections.<String, String> emptyMap()); + } + static String getSHA256(String uri) throws IOException, NoSuchAlgorithmException // TODO find a good place for this { InputStream is = new URL(uri).openStream(); Modified: felix/trunk/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/OSGiRepositoryImplTest.java URL: http://svn.apache.org/viewvc/felix/trunk/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/OSGiRepositoryImplTest.java?rev=1563948&r1=1563947&r2=1563948&view=diff ============================================================================== --- felix/trunk/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/OSGiRepositoryImplTest.java (original) +++ felix/trunk/bundlerepository/src/test/java/org/apache/felix/bundlerepository/impl/OSGiRepositoryImplTest.java Mon Feb 3 15:22:25 2014 @@ -40,9 +40,38 @@ import org.osgi.resource.Requirement; import org.osgi.resource.Resource; import org.osgi.service.repository.ContentNamespace; import org.osgi.service.repository.Repository; +import org.osgi.service.repository.RepositoryContent; public class OSGiRepositoryImplTest extends TestCase { + public void testRepositoryContent() throws Exception { + RepositoryAdminImpl repoAdmin = createRepositoryAdmin(); + URL url = getClass().getResource("/another_repository.xml"); + repoAdmin.addRepository(url); + + Repository repo = new OSGiRepositoryImpl(repoAdmin); + Requirement req = new OSGiRequirementImpl("osgi.wiring.package", + "(&(osgi.wiring.package=org.apache.commons.logging)(version>=1.0.1)(!(version>=2)))"); + + Map<Requirement, Collection<Capability>> result = repo.findProviders(Collections.singleton(req)); + assertEquals(1, result.size()); + Collection<Capability> caps = result.values().iterator().next(); + assertEquals(1, caps.size()); + Capability cap = caps.iterator().next(); + assertEquals("osgi.wiring.package", cap.getNamespace()); + assertEquals("org.apache.commons.logging", cap.getAttributes().get("osgi.wiring.package")); + assertEquals(Version.parseVersion("1.0.4"), cap.getAttributes().get("version")); + + Resource resource = cap.getResource(); + RepositoryContent rc = (RepositoryContent) resource; // Repository Resources must implement this interface + byte[] actualBytes = Streams.suck(rc.getContent()); + + URL actualURL = getClass().getResource("/repo_files/test_file_1.jar"); + byte[] expectedBytes = Streams.suck(actualURL.openStream()); + + assertTrue(Arrays.equals(expectedBytes, actualBytes)); + } + public void testIdentityAndContentCapabilities() throws Exception { RepositoryAdminImpl repoAdmin = createRepositoryAdmin();