You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by da...@apache.org on 2018/04/27 09:53:22 UTC

[sling-org-apache-sling-feature-analyser] 06/28: SLING-7521 Order bundles in the generated app based on feature order and start order

This is an automated email from the ASF dual-hosted git repository.

davidb pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-analyser.git

commit feb614536d324daf7ea592d990326372a21b54c3
Author: David Bosschaert <bo...@adobe.com>
AuthorDate: Mon Mar 5 15:05:23 2018 +0000

    SLING-7521 Order bundles in the generated app based on feature order and start order
    
    Order resource (bundles and features) in the resulting application based on the order
    of resolved features and then also in the order of the start order within the feature.
---
 .../sling/feature/analyser/AnalyserTest.java       |  33 ++-
 .../feature/analyser/TestBundleResourceImpl.java   | 231 +++++++++++++++++++++
 src/test/resources/feature_complete.json           |  38 ++--
 src/test/resources/feature_incomplete.json         |  38 ++--
 4 files changed, 300 insertions(+), 40 deletions(-)

diff --git a/src/test/java/org/apache/sling/feature/analyser/AnalyserTest.java b/src/test/java/org/apache/sling/feature/analyser/AnalyserTest.java
index d92398a..bff0af9 100644
--- a/src/test/java/org/apache/sling/feature/analyser/AnalyserTest.java
+++ b/src/test/java/org/apache/sling/feature/analyser/AnalyserTest.java
@@ -17,7 +17,10 @@
 package org.apache.sling.feature.analyser;
 
 import org.apache.sling.feature.Application;
+import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.FeatureResource;
+import org.apache.sling.feature.analyser.impl.BundleDescriptorImpl;
 import org.apache.sling.feature.analyser.service.Analyser;
 import org.apache.sling.feature.analyser.service.Scanner;
 import org.apache.sling.feature.process.FeatureResolver;
@@ -27,8 +30,11 @@ import org.apache.sling.feature.support.FeatureUtil;
 import org.apache.sling.feature.support.json.FeatureJSONReader;
 import org.junit.Test;
 
+import java.io.File;
+import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.Reader;
+import java.util.ArrayList;
 import java.util.List;
 
 import static junit.framework.TestCase.fail;
@@ -78,8 +84,31 @@ public class AnalyserTest {
             }
 
             @Override
-            public List<Feature> orderFeatures(List<Feature> features) {
-                return features;
+            public List<FeatureResource> orderResources(List<Feature> features) {
+                try {
+                    // Just return the resources in the same order as they are listed in the features
+                    List<FeatureResource> l = new ArrayList<>();
+
+                    for (Feature f : features) {
+                        for (Artifact a : f.getBundles()) {
+                            BundleDescriptor bd = getBundleDescriptor(ArtifactManager.getArtifactManager(new ArtifactManagerConfig()), a);
+                            l.add(new TestBundleResourceImpl(bd, f));
+                        }
+                    }
+
+                    return l;
+                } catch (IOException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+
+            private BundleDescriptor getBundleDescriptor(ArtifactManager artifactManager, Artifact b) throws IOException {
+                final File file = artifactManager.getArtifactHandler(b.getId().toMvnUrl()).getFile();
+                if ( file == null ) {
+                    throw new IOException("Unable to find file for " + b.getId());
+                }
+
+                return new BundleDescriptorImpl(b, file, -1);
             }
         };
     }
diff --git a/src/test/java/org/apache/sling/feature/analyser/TestBundleResourceImpl.java b/src/test/java/org/apache/sling/feature/analyser/TestBundleResourceImpl.java
new file mode 100644
index 0000000..c06affe
--- /dev/null
+++ b/src/test/java/org/apache/sling/feature/analyser/TestBundleResourceImpl.java
@@ -0,0 +1,231 @@
+/*
+ * 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.analyser;
+
+import org.apache.sling.feature.Artifact;
+import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.FeatureResource;
+import org.apache.sling.feature.OSGiCapability;
+import org.apache.sling.feature.OSGiRequirement;
+import org.apache.sling.feature.support.util.PackageInfo;
+import org.osgi.framework.Version;
+import org.osgi.framework.VersionRange;
+import org.osgi.framework.namespace.BundleNamespace;
+import org.osgi.framework.namespace.ExecutionEnvironmentNamespace;
+import org.osgi.framework.namespace.PackageNamespace;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * Implementation of the OSGi Resource interface, used by the test
+ */
+public class TestBundleResourceImpl implements FeatureResource {
+    final Artifact artifact;
+    final String bsn;
+    final Version version;
+    final Map<String, List<Capability>> capabilities;
+    final Map<String, List<Requirement>> requirements;
+    final Feature feature;
+
+    /**
+     * Create a resource based on a BundleDescriptor.
+     * @param bd The BundleDescriptor to represent.
+     */
+    public TestBundleResourceImpl(BundleDescriptor bd, Feature feat) {
+        artifact = bd.getArtifact();
+        bsn = bd.getBundleSymbolicName();
+        version = bd.getArtifact().getId().getOSGiVersion();
+        feature = feat;
+
+        Map<String, List<Capability>> caps = new HashMap<>();
+        for (Capability c : bd.getCapabilities()) {
+            List<Capability> l = caps.get(c.getNamespace());
+            if (l == null) {
+                l = new ArrayList<>();
+                caps.put(c.getNamespace(), l);
+            }
+            l.add(new OSGiCapability(this, c));
+        }
+
+        // Add the package capabilities (export package)
+        List<Capability> pkgCaps = new ArrayList<>();
+        for(PackageInfo exported : bd.getExportedPackages()) {
+            Map<String, Object> attrs = new HashMap<>();
+            attrs.put(PackageNamespace.PACKAGE_NAMESPACE, exported.getName());
+            attrs.put(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE, exported.getPackageVersion());
+            attrs.put(PackageNamespace.CAPABILITY_BUNDLE_SYMBOLICNAME_ATTRIBUTE, bd.getBundleSymbolicName());
+            attrs.put(PackageNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE, new Version(bd.getBundleVersion()));
+            pkgCaps.add(new OSGiCapability(this, PackageNamespace.PACKAGE_NAMESPACE, attrs, Collections.emptyMap()));
+        }
+        caps.put(PackageNamespace.PACKAGE_NAMESPACE, Collections.unmodifiableList(pkgCaps));
+
+        // Add the bundle capability
+        Map<String, Object> battrs = new HashMap<>();
+        battrs.put(BundleNamespace.BUNDLE_NAMESPACE, bd.getBundleSymbolicName());
+        battrs.put(BundleNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE, new Version(bd.getBundleVersion()));
+        OSGiCapability bundleCap = new OSGiCapability(this, BundleNamespace.BUNDLE_NAMESPACE, battrs, Collections.emptyMap());
+        caps.put(BundleNamespace.BUNDLE_NAMESPACE, Collections.singletonList(bundleCap));
+        capabilities = Collections.unmodifiableMap(caps);
+
+        Map<String, List<Requirement>> reqs = new HashMap<>();
+        for (Requirement r : bd.getRequirements()) {
+            List<Requirement> l = reqs.get(r.getNamespace());
+            if (l == null) {
+                l = new ArrayList<>();
+                reqs.put(r.getNamespace(), l);
+            }
+            // Add the requirement and associate with this resource
+            l.add(new OSGiRequirement(this, r));
+        }
+
+        // TODO What do we do with the execution environment?
+        reqs.remove(ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE);
+
+        // Add the package requirements (import package)
+        List<Requirement> pkgReqs = new ArrayList<>();
+        for(PackageInfo imported : bd.getImportedPackages()) {
+            Map<String, String> dirs = new HashMap<>();
+            VersionRange range = imported.getPackageVersionRange();
+            String rangeFilter;
+            if (range != null) {
+                rangeFilter = range.toFilterString(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE);
+            } else {
+                rangeFilter = "";
+            }
+            dirs.put(PackageNamespace.REQUIREMENT_FILTER_DIRECTIVE,
+                "(&(" + PackageNamespace.PACKAGE_NAMESPACE + "=" + imported.getName() + ")" + rangeFilter + ")");
+            if (imported.isOptional())
+                dirs.put(PackageNamespace.REQUIREMENT_RESOLUTION_DIRECTIVE,
+                    PackageNamespace.RESOLUTION_OPTIONAL);
+            pkgReqs.add(new OSGiRequirement(this, PackageNamespace.PACKAGE_NAMESPACE, Collections.emptyMap(), dirs));
+        }
+        reqs.put(PackageNamespace.PACKAGE_NAMESPACE, Collections.unmodifiableList(pkgReqs));
+        requirements = Collections.unmodifiableMap(reqs);
+    }
+
+    @Override
+    public Artifact getArtifact() {
+        return artifact;
+    }
+
+    @Override
+    public String getId() {
+        return bsn;
+    }
+
+    @Override
+    public Version getVersion() {
+        return version;
+    }
+
+    @Override
+    public List<Capability> getCapabilities(String namespace) {
+        if (namespace == null) {
+            return capabilities.values().stream().flatMap(Collection::stream).collect(Collectors.toList());
+        }
+
+        List<Capability> caps = capabilities.get(namespace);
+        if (caps == null)
+            return Collections.emptyList();
+        return caps;
+    }
+
+    @Override
+    public List<Requirement> getRequirements(String namespace) {
+        if (namespace == null) {
+            return requirements.values().stream().flatMap(Collection::stream).collect(Collectors.toList());
+        }
+
+        List<Requirement> reqs = requirements.get(namespace);
+        if (reqs == null)
+            return Collections.emptyList();
+        return reqs;
+    }
+
+    @Override
+    public Feature getFeature() {
+        return feature;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((artifact == null) ? 0 : artifact.hashCode());
+        result = prime * result + ((bsn == null) ? 0 : bsn.hashCode());
+        result = prime * result + ((capabilities == null) ? 0 : capabilities.hashCode());
+        result = prime * result + ((feature == null) ? 0 : feature.hashCode());
+        result = prime * result + ((requirements == null) ? 0 : requirements.hashCode());
+        result = prime * result + ((version == null) ? 0 : version.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        TestBundleResourceImpl other = (TestBundleResourceImpl) obj;
+        if (artifact == null) {
+            if (other.artifact != null)
+                return false;
+        } else if (!artifact.equals(other.artifact))
+            return false;
+        if (bsn == null) {
+            if (other.bsn != null)
+                return false;
+        } else if (!bsn.equals(other.bsn))
+            return false;
+        if (capabilities == null) {
+            if (other.capabilities != null)
+                return false;
+        } else if (!capabilities.equals(other.capabilities))
+            return false;
+        if (feature == null) {
+            if (other.feature != null)
+                return false;
+        } else if (!feature.equals(other.feature))
+            return false;
+        if (requirements == null) {
+            if (other.requirements != null)
+                return false;
+        } else if (!requirements.equals(other.requirements))
+            return false;
+        if (version == null) {
+            if (other.version != null)
+                return false;
+        } else if (!version.equals(other.version))
+            return false;
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return "BundleResourceImpl [" + bsn + " " + version + "]";
+    }
+}
diff --git a/src/test/resources/feature_complete.json b/src/test/resources/feature_complete.json
index 63b8bd0..6271a9c 100644
--- a/src/test/resources/feature_complete.json
+++ b/src/test/resources/feature_complete.json
@@ -4,79 +4,79 @@
     "bundles" : [
         {
           "id" : "org.apache.sling/org.apache.sling.commons.log/5.0.0",
-          "startOrder" : 1
+          "start-order" : 1
         },
         {
           "id" : "org.apache.sling/org.apache.sling.commons.logservice/1.0.6",
-          "startOrder" : 1
+          "start-order" : 1
         },
         {
           "id" : "org.slf4j/jcl-over-slf4j/1.7.21",
-          "startOrder" : 1
+          "start-order" : 1
         },
         {
           "id" : "org.slf4j/log4j-over-slf4j/1.7.21",
-          "startOrder" : 1
+          "start-order" : 1
         },
         {
           "id" : "org.slf4j/slf4j-api/1.7.21",
-          "startOrder" : 1
+          "start-order" : 1
         },
         {
           "id" : "org.apache.felix/org.apache.felix.configadmin/1.8.14",
-          "startOrder" : 1
+          "start-order" : 1
         },
         {
           "id" : "org.apache.felix/org.apache.felix.eventadmin/1.4.8",
-          "startOrder" : 4
+          "start-order" : 4
         },
         {
           "id" : "org.apache.felix/org.apache.felix.metatype/1.1.2",
-          "startOrder" : 4
+          "start-order" : 4
         },
         {
           "id" : "org.apache.felix/org.apache.felix.scr/2.0.12",
-          "startOrder" : 4
+          "start-order" : 4
         },
         {
           "id" : "org.apache.felix/org.apache.felix.http.jetty/3.4.2",
-          "startOrder" : 5
+          "start-order" : 5
         },
         {
           "id" : "org.apache.felix/org.apache.felix.http.servlet-api/1.1.2",
-          "startOrder" : 5
+          "start-order" : 5
         },
         {
           "id" : "commons-io/commons-io/2.5",
-          "startOrder" : 5
+          "start-order" : 5
         },
         {
           "id" : "commons-fileupload/commons-fileupload/1.3.2",
-          "startOrder" : 5
+          "start-order" : 5
         },
         {
           "id" : "org.apache.felix/org.apache.felix.inventory/1.0.4",
-          "startOrder" : 5
+          "start-order" : 5
         },
         {
           "id" : "org.apache.felix/org.apache.felix.webconsole.plugins.ds/2.0.6",
-          "startOrder" : 5
+          "start-order" : 5
         },
         {
           "id" : "org.apache.felix/org.apache.felix.webconsole.plugins.event/1.1.6",
-          "startOrder" : 5
+          "start-order" : 5
         },
         {
           "id" : "org.apache.felix/org.apache.felix.webconsole.plugins.packageadmin/1.0.4",
-          "startOrder" : 5
+          "start-order" : 5
         },
         {
           "id" : "org.apache.felix/org.apache.felix.webconsole/4.3.4",
-          "startOrder" : 5
+          "start-order" : 5
         },
         {
           "id" : "org.apache.sling/org.apache.sling.commons.log.webconsole/1.0.0",
-          "startOrder" : 5
+          "start-order" : 5
         }
     ]
 }
diff --git a/src/test/resources/feature_incomplete.json b/src/test/resources/feature_incomplete.json
index 3ab884c..514e878 100644
--- a/src/test/resources/feature_incomplete.json
+++ b/src/test/resources/feature_incomplete.json
@@ -4,79 +4,79 @@
     "bundles" : [
         {
           "id" : "org.apache.sling/org.apache.sling.commons.log/5.0.0",
-          "startOrder" : 1
+          "start-order" : 1
         },
         {
           "id" : "org.apache.sling/org.apache.sling.commons.logservice/1.0.6",
-          "startOrder" : 1
+          "start-order" : 1
         },
         {
           "id" : "org.slf4j/jcl-over-slf4j/1.7.21",
-          "startOrder" : 1
+          "start-order" : 1
         },
         {
           "id" : "org.slf4j/log4j-over-slf4j/1.7.21",
-          "startOrder" : 1
+          "start-order" : 1
         },
         {
           "id" : "org.slf4j/slf4j-api/1.7.21",
-          "startOrder" : 1
+          "start-order" : 1
         },
         {
           "id" : "org.apache.felix/org.apache.felix.configadmin/1.8.14",
-          "startOrder" : 1
+          "start-order" : 1
         },
         {
           "id" : "org.apache.felix/org.apache.felix.eventadmin/1.4.8",
-          "startOrder" : 4
+          "start-order" : 4
         },
         {
           "id" : "org.apache.felix/org.apache.felix.metatype/1.1.2",
-          "startOrder" : 4
+          "start-order" : 4
         },
         {
           "id" : "org.apache.felix/org.apache.felix.scr/2.0.12",
-          "startOrder" : 4
+          "start-order" : 4
         },
         {
           "id" : "org.apache.felix/org.apache.felix.http.servlet-api/1.1.2",
-          "startOrder" : 5
+          "start-order" : 5
         },
         {
           "id" : "commons-io/commons-io/2.5",
-          "startOrder" : 5
+          "start-order" : 5
         },
         {
           "id" : "commons-fileupload/commons-fileupload/1.3.2",
-          "startOrder" : 5
+          "start-order" : 5
         },
         {
           "id" : "org.apache.felix/org.apache.felix.inventory/1.0.4",
-          "startOrder" : 5
+          "start-order" : 5
         },
         {
           "id" : "org.apache.felix/org.apache.felix.webconsole.plugins.ds/2.0.6",
-          "startOrder" : 5
+          "start-order" : 5
         },
         {
           "id" : "org.apache.felix/org.apache.felix.webconsole.plugins.event/1.1.6",
-          "startOrder" : 5
+          "start-order" : 5
         },
         {
           "id" : "org.apache.felix/org.apache.felix.webconsole.plugins.packageadmin/1.0.4",
-          "startOrder" : 5
+          "start-order" : 5
         },
         {
           "id" : "org.apache.felix/org.apache.felix.webconsole/4.3.4",
-          "startOrder" : 5
+          "start-order" : 5
         },
         {
           "id" : "org.apache.sling/org.apache.sling.commons.log.webconsole/1.0.0",
-          "startOrder" : 5
+          "start-order" : 5
         },
         {
           "id" : "org.apache.sling/org.apache.sling.i18n/2.5.8",
-          "startOrder" : 6
+          "start-order" : 6
         }
     ]
 }

-- 
To stop receiving notification emails like this one, please contact
davidb@apache.org.