| /* |
| * 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.sling.feature.resolver.impl; |
| |
| import org.apache.felix.utils.resource.CapabilityImpl; |
| import org.apache.felix.utils.resource.RequirementImpl; |
| import org.apache.sling.feature.Artifact; |
| import org.apache.sling.feature.ArtifactId; |
| import org.apache.sling.feature.Feature; |
| import org.apache.sling.feature.resolver.FeatureResource; |
| import org.apache.sling.feature.scanner.BundleDescriptor; |
| import org.apache.sling.feature.scanner.impl.BundleDescriptorImpl; |
| import org.junit.Test; |
| import org.mockito.Mockito; |
| import org.osgi.framework.Constants; |
| import org.osgi.framework.Version; |
| import org.osgi.framework.namespace.BundleNamespace; |
| import org.osgi.framework.namespace.PackageNamespace; |
| import org.osgi.resource.Capability; |
| import org.osgi.resource.Requirement; |
| import org.osgi.resource.Resource; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Set; |
| import java.util.jar.JarOutputStream; |
| import java.util.jar.Manifest; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertSame; |
| import static org.junit.Assert.assertTrue; |
| |
| public class BundleResourceImplTest { |
| @Test |
| public void testResource() throws Exception { |
| String bmf = "Bundle-SymbolicName: foobar\n" |
| + "Bundle-Version: 1.2.3\n" |
| + "Bundle-ManifestVersion: 2\n" |
| + "Provide-Capability: ns.1;ns.1=\"c1\",ns.1;ns.1=\"c2\",ns.2;ns.2=\"c3\"\n" |
| + "Require-Capability: ns.1;mydir:=\"myvalue\"\n"; |
| File f = createBundle(bmf); |
| |
| Artifact artifact = new Artifact(new ArtifactId("grp", "a.b.c", "1.2.3", null, null)); |
| BundleDescriptor bd = new BundleDescriptorImpl(artifact, f, 1); |
| Feature feat = Mockito.mock(Feature.class); |
| FeatureResource res = new BundleResourceImpl(bd, feat); |
| |
| Capability c1 = new CapabilityImpl(res, "ns.1", null, |
| Collections.singletonMap("ns.1", "c1")); |
| Capability c2 = new CapabilityImpl(res, "ns.1", null, |
| Collections.singletonMap("ns.1", "c2")); |
| List<Capability> expectedCaps1 = Arrays.asList(c1, c2); |
| |
| Capability c3 = new CapabilityImpl(res, "ns.2", null, |
| Collections.singletonMap("ns.2", "c3")); |
| List<Capability> expectedCaps2 = Collections.singletonList(c3); |
| |
| Requirement r1 = new RequirementImpl(res, "ns.1", |
| Collections.singletonMap("mydir", "myvalue"), null); |
| List<Requirement> expectedReqs = Collections.singletonList(r1); |
| |
| assertEquals(0, res.getCapabilities("nonexistent").size()); |
| assertEquals(0, res.getRequirements("ns.2").size()); |
| List<Capability> caps = res.getCapabilities("ns.1"); |
| assertEquals(expectedCaps1.size(), caps.size()); |
| assertTrue(expectedCaps1.containsAll(caps)); |
| assertEquals(expectedReqs, res.getRequirements("ns.1")); |
| |
| List<Capability> mergedCaps = res.getCapabilities(null); |
| assertTrue(mergedCaps.containsAll(expectedCaps1)); |
| assertTrue(mergedCaps.containsAll(expectedCaps2)); |
| assertEquals(expectedReqs, res.getRequirements(null)); |
| |
| assertEquals("foobar", res.getId()); |
| assertEquals(new Version("1.2.3"), res.getVersion()); |
| assertSame(feat, res.getFeature()); |
| } |
| |
| @Test |
| public void testBundleResource() throws Exception { |
| ArtifactId id = new ArtifactId("grp", "art", "1.2.3", null, null); |
| Artifact artifact = new Artifact(id); |
| |
| String bmf = "Bundle-SymbolicName: " + Constants.SYSTEM_BUNDLE_SYMBOLICNAME + "\n" |
| + "Bundle-Version: 1.2.3\n" |
| + "Bundle-ManifestVersion: 2\n" |
| + "Export-Package: org.foo.a;version=0.0.1.SNAPSHOT\n" |
| + "Import-Package: org.bar;version=\"[1,2)\",org.tar;resolution:=\"optional\"\n"; |
| File f = createBundle(bmf); |
| |
| BundleDescriptor bd = new BundleDescriptorImpl(artifact, f, 1); |
| Resource res = new BundleResourceImpl(bd, null); |
| |
| assertNotNull( |
| getCapAttribute(res, BundleNamespace.BUNDLE_NAMESPACE, BundleNamespace.BUNDLE_NAMESPACE)); |
| assertEquals(new Version("1.2.3"), |
| getCapAttribute(res, BundleNamespace.BUNDLE_NAMESPACE, BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE)); |
| |
| List<Capability> exports = res.getCapabilities(PackageNamespace.PACKAGE_NAMESPACE); |
| assertEquals(1, exports.size()); |
| assertEquals("org.foo.a", |
| getCapAttribute(res, PackageNamespace.PACKAGE_NAMESPACE, PackageNamespace.PACKAGE_NAMESPACE)); |
| assertEquals(new Version("0.0.1.SNAPSHOT"), |
| getCapAttribute(res, PackageNamespace.PACKAGE_NAMESPACE, PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE)); |
| assertEquals(getCapAttribute(res, BundleNamespace.BUNDLE_NAMESPACE, BundleNamespace.BUNDLE_NAMESPACE), |
| getCapAttribute(res, PackageNamespace.PACKAGE_NAMESPACE, PackageNamespace.CAPABILITY_BUNDLE_SYMBOLICNAME_ATTRIBUTE)); |
| assertEquals(new Version("1.2.3"), |
| getCapAttribute(res, PackageNamespace.PACKAGE_NAMESPACE, PackageNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE)); |
| |
| List<Requirement> requirements = res.getRequirements(PackageNamespace.PACKAGE_NAMESPACE); |
| assertEquals(2, requirements.size()); |
| |
| Requirement reqBar = null; |
| Requirement reqTar = null; |
| for (Requirement req : requirements) { |
| if (req.getDirectives().get("filter").contains("org.bar")) |
| reqBar = req; |
| else |
| reqTar = req; |
| } |
| |
| assertEquals(1, reqBar.getDirectives().size()); |
| assertEquals("(&(osgi.wiring.package=org.bar)(version>=1.0.0)(!(version>=2.0.0)))", |
| reqBar.getDirectives().get(PackageNamespace.REQUIREMENT_FILTER_DIRECTIVE)); |
| |
| assertEquals(2, reqTar.getDirectives().size()); |
| assertEquals("(osgi.wiring.package=org.tar)", |
| reqTar.getDirectives().get(PackageNamespace.REQUIREMENT_FILTER_DIRECTIVE)); |
| assertEquals(PackageNamespace.RESOLUTION_OPTIONAL, |
| reqTar.getDirectives().get(PackageNamespace.REQUIREMENT_RESOLUTION_DIRECTIVE)); |
| } |
| |
| @Test |
| public void testBundleResourceGenericCapReq() throws Exception { |
| String bmf = "Bundle-SymbolicName: org.apache.someartifact\n" |
| + "Bundle-Version: 0.0.0\n" |
| + "Bundle-ManifestVersion: 2\n" |
| + "Provide-Capability: org.example.cap1;intAttr=\"999\";somedir:=\"mydir\"\n" |
| + "Require-Capability: org.example.req1;adir:=\"aval\";verAttr=\"1.2.3\"," |
| + "org.example.req2;adir:=\"aval2\";verAttr=\"3.2.1\"\n"; |
| File f = createBundle(bmf); |
| |
| ArtifactId id = new ArtifactId("org.apache", "org.apache.someartifact", "0.0.0", null, null); |
| Artifact artifact = new Artifact(id); |
| |
| BundleDescriptorImpl bd = new BundleDescriptorImpl(artifact, f, 1); |
| Resource res = new BundleResourceImpl(bd, null); |
| |
| Capability cap = new CapabilityImpl(res, "org.example.cap1", |
| Collections.singletonMap("somedir", "mydir"), |
| Collections.singletonMap("intAttr", "999")); |
| Set<Capability> caps = Collections.singleton(cap); |
| |
| Requirement req1 = new RequirementImpl(res, "org.example.req1", |
| Collections.singletonMap("adir", "aval"), |
| Collections.singletonMap("verAttr", "1.2.3")); |
| Requirement req2 = new RequirementImpl(res, "org.example.req2", |
| Collections.singletonMap("adir", "aval2"), |
| Collections.singletonMap("verAttr", "3.2.1")); |
| assertEquals(caps, new HashSet<>(res.getCapabilities("org.example.cap1"))); |
| |
| assertEquals(Collections.singleton(req1), |
| new HashSet<>(res.getRequirements("org.example.req1"))); |
| assertEquals(Collections.singleton(req2), |
| new HashSet<>(res.getRequirements("org.example.req2"))); |
| assertEquals(new HashSet<>(Arrays.asList(req1, req2)), |
| new HashSet<>(res.getRequirements(null))); |
| } |
| |
| private File createBundle(String manifest) throws IOException |
| { |
| File f = File.createTempFile("bundle", ".jar"); |
| f.deleteOnExit(); |
| Manifest mf = new Manifest(new ByteArrayInputStream(manifest.getBytes("UTF-8"))); |
| mf.getMainAttributes().putValue("Manifest-Version", "1.0"); |
| JarOutputStream os = new JarOutputStream(new FileOutputStream(f), mf); |
| os.close(); |
| return f; |
| } |
| |
| private Object getCapAttribute(Resource res, String ns, String attr) { |
| List<Capability> caps = res.getCapabilities(ns); |
| if (caps.size() == 0) |
| return null; |
| |
| Capability cap = caps.iterator().next(); |
| return cap.getAttributes().get(attr); |
| } |
| } |