blob: c82995840671446c036e9f91517902f33e84fe29 [file] [log] [blame]
/*
* 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.Descriptor;
import org.apache.sling.feature.scanner.impl.BundleDescriptorImpl;
import org.apache.sling.feature.scanner.PackageInfo;
import org.junit.Ignore;
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.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
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.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
public class BundleResourceImplTest {
@Test
public void testResource() {
Map<String, List<Capability>> caps = new HashMap<>();
Capability c1 = new CapabilityImpl(null, "ns.1", null,
Collections.singletonMap("ns.1", "c1"));
Capability c2 = new CapabilityImpl(null, "ns.1", null,
Collections.singletonMap("ns.1", "c2"));
List<Capability> capLst1 = Arrays.asList(c1, c2);
caps.put("ns.1", capLst1);
Capability c3 = new CapabilityImpl(null, "ns.2", null,
Collections.singletonMap("ns.2", "c3"));
List<Capability> capLst2 = Collections.singletonList(c3);
caps.put("ns.2", capLst2);
Requirement r1 = new RequirementImpl(null, "ns.1",
Collections.singletonMap("mydir", "myvalue"), null);
List<Requirement> reqList = Collections.singletonList(r1);
Artifact art = Mockito.mock(Artifact.class);
Feature feat = Mockito.mock(Feature.class);
FeatureResource res = new BundleResourceImpl("a.b.c", "1.2.3", art, feat, caps,
Collections.singletonMap("ns.1", reqList));
assertEquals(0, res.getCapabilities("nonexistent").size());
assertEquals(0, res.getRequirements("ns.2").size());
assertEquals(capLst1, res.getCapabilities("ns.1"));
assertEquals(reqList, res.getRequirements("ns.1"));
List<Capability> mergedCaps = res.getCapabilities(null);
assertEquals(3, mergedCaps.size());
assertTrue(mergedCaps.containsAll(capLst1));
assertTrue(mergedCaps.containsAll(capLst2));
assertEquals(reqList, res.getRequirements(null));
assertEquals("a.b.c", res.getId());
assertEquals(new Version("1.2.3"), res.getVersion());
assertSame(art, res.getArtifact());
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 {
ArtifactId id = new ArtifactId("org.apache", "org.apache.someartifact", "0.0.0", null, null);
Artifact artifact = new Artifact(id);
Capability cap = new CapabilityImpl(null, "org.example.cap1",
Collections.singletonMap("somedir", "mydir"),
Collections.singletonMap("intAttr", 999));
Set<Capability> caps = Collections.singleton(cap);
Requirement req1 = new RequirementImpl(null, "org.example.req1",
Collections.singletonMap("adir", "aval"),
Collections.singletonMap("boolAttr", true));
Requirement req2 = new RequirementImpl(null, "org.example.req2",
Collections.singletonMap("adir", "aval2"),
Collections.singletonMap("boolAttr", false));
Set<Requirement> reqs = new HashSet<>(Arrays.asList(req1, req2));
BundleDescriptorImpl bd = new BundleDescriptorImpl(artifact, Collections.emptySet(), reqs, caps);
Resource res = new BundleResourceImpl(bd, null);
Set<Capability> caps2 = new HashSet<>();
for (Capability c : res.getCapabilities("org.example.cap1")) {
caps2.add(new CapabilityImpl(null, c));
}
assertEquals(caps, caps2);
// For comparison create an expected requirement that has the resource set in it.
RequirementImpl expectedReq1 = new RequirementImpl(res.getRequirements("org.example.req1").get(0).getResource(), req1);
assertEquals(Collections.singleton(expectedReq1),
new HashSet<>(res.getRequirements("org.example.req1")));
RequirementImpl expectedReq2 = new RequirementImpl(res.getRequirements("org.example.req2").get(0).getResource(), req2);
assertEquals(Collections.singleton(expectedReq2),
new HashSet<>(res.getRequirements("org.example.req2")));
assertEquals(new HashSet<>(Arrays.asList(expectedReq1, expectedReq2)),
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);
}
private void setField(Class<?> cls, String field, Object obj, Object val) throws Exception {
Field f = cls.getDeclaredField(field);
f.setAccessible(true);
f.set(obj, val);
}
}