You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by pa...@apache.org on 2020/10/08 12:12:42 UTC

[sling-org-apache-sling-feature-analyser] branch SLING-8481 created (now 91ec325)

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

pauls pushed a change to branch SLING-8481
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-analyser.git.


      at 91ec325  SLING-8481: add a caching extension for meta-data.

This branch includes the following new commits:

     new 91ec325  SLING-8481: add a caching extension for meta-data.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[sling-org-apache-sling-feature-analyser] 01/01: SLING-8481: add a caching extension for meta-data.

Posted by pa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 91ec325ae56993b204b9bf06f11dd1046a354453
Author: Karl Pauls <ka...@gmail.com>
AuthorDate: Thu Oct 8 14:12:22 2020 +0200

    SLING-8481: add a caching extension for meta-data.
---
 .../org/apache/sling/feature/scanner/Scanner.java  | 54 ++++++++++++---
 .../feature/scanner/impl/BundleDescriptorImpl.java | 22 +++++--
 .../scanner/impl/BundleDescriptorImplTest.java     | 26 ++++++--
 src/test/resources/metadata-feature.json           | 76 ++++++++++++++++++++++
 4 files changed, 158 insertions(+), 20 deletions(-)

diff --git a/src/main/java/org/apache/sling/feature/scanner/Scanner.java b/src/main/java/org/apache/sling/feature/scanner/Scanner.java
index 7373240..578010e 100644
--- a/src/main/java/org/apache/sling/feature/scanner/Scanner.java
+++ b/src/main/java/org/apache/sling/feature/scanner/Scanner.java
@@ -16,14 +16,12 @@
  */
 package org.apache.sling.feature.scanner;
 
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.ServiceLoader;
-import java.util.TreeMap;
+import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.jar.Manifest;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -38,6 +36,9 @@ import org.apache.sling.feature.scanner.impl.FeatureDescriptorImpl;
 import org.apache.sling.feature.scanner.spi.ExtensionScanner;
 import org.apache.sling.feature.scanner.spi.FrameworkScanner;
 
+import javax.json.JsonObject;
+import javax.json.JsonValue;
+
 /**
  * The scanner is a service that scans items and provides descriptions for
  * these. The following items can be scanned individually
@@ -141,11 +142,14 @@ public class Scanner {
         BundleDescriptor desc = (BundleDescriptor) this.cache.get(key);
         if (desc == null) {
             final URL file = artifactProvider.provide(bundle.getId());
-            if (file == null) {
+            if (bundle.getMetadata().containsKey("bundle-manifest")) {
+                Manifest mf = new Manifest(new ByteArrayInputStream(bundle.getMetadata().get("bundle-manifest").getBytes("UTF-8")));
+                desc = new BundleDescriptorImpl(bundle, file, mf, startLevel);
+            } else if (file != null) {
+                desc = new BundleDescriptorImpl(bundle, file, startLevel);
+            } else {
                 throw new IOException("Unable to find file for " + bundle.getId());
             }
-
-            desc = new BundleDescriptorImpl(bundle, file, startLevel);
             this.cache.put(key, desc);
         }
         return desc;
@@ -176,6 +180,9 @@ public class Scanner {
     private void scanExtensions(final Feature f, final ContainerDescriptor desc)
     throws IOException {
         for (final Extension ext : f.getExtensions()) {
+            if (ext.getName().equals("analyser-metadata")) {
+                continue;
+            }
             ContainerDescriptor extDesc = null;
             for(final ExtensionScanner scanner : this.extensionScanners) {
                 extDesc = scanner.scan(f, ext, this.artifactProvider);
@@ -222,6 +229,7 @@ public class Scanner {
         if (desc == null) {
             desc = new FeatureDescriptorImpl(feature);
 
+            populateCache(feature);
             getBundleInfos(feature.getBundles(), desc);
             scanExtensions(feature, desc);
 
@@ -234,6 +242,36 @@ public class Scanner {
         return desc;
     }
 
+
+    private void populateCache(Feature feature) throws IOException {
+        Extension extension = feature.getExtensions().getByName("analyser-metadata");
+        if (extension != null) {
+            JsonObject json = extension.getJSONStructure().asJsonObject();
+            for (Map.Entry<String, JsonValue> entry : json.entrySet()) {
+                ArtifactId id = ArtifactId.fromMvnId(entry.getKey());
+                if (feature.getBundles().containsExact(id)) {
+                    Artifact bundle = feature.getBundles().getExact(id);
+                    final String key = id.toMvnId().concat(":")
+                            .concat(String.valueOf(bundle.getStartOrder())).concat(":")
+                            .concat(Stream.of(bundle.getFeatureOrigins()).map(ArtifactId::toMvnId).collect(Collectors.joining(",")));
+                    if (this.cache.get(key) == null) {
+                        JsonObject headers = entry.getValue().asJsonObject();
+                        if (headers.containsKey("manifest")) {
+                            final URL file = artifactProvider.provide(id);
+                            Manifest manifest = new Manifest();
+                            JsonObject manifestHeaders = headers.getJsonObject("manifest");
+                            for (String name : manifestHeaders.keySet()) {
+                                manifest.getMainAttributes().putValue(name, manifestHeaders.getString(name));
+                            }
+                            BundleDescriptor desc = new BundleDescriptorImpl(bundle, file, manifest, bundle.getStartOrder());
+                            this.cache.put(key, desc);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     /**
      * Scan a framework
      *
diff --git a/src/main/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImpl.java b/src/main/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImpl.java
index 74cf932..641d269 100644
--- a/src/main/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImpl.java
+++ b/src/main/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImpl.java
@@ -62,19 +62,31 @@ public class BundleDescriptorImpl
     /** The corresponding artifact from the feature. */
     private final Artifact artifact;
 
+    private static Manifest getManifest(URL file) throws IOException {
+        try (JarFile jarFile = IOUtils.getJarFileFromURL(file, true, null)) {
+            return jarFile.getManifest();
+        }
+    }
+
     public BundleDescriptorImpl(final Artifact a,
             final URL file,
             final int startLevel) throws IOException  {
+        this(a, file, getManifest(file), startLevel);
+    }
+
+    public BundleDescriptorImpl(final Artifact a,
+                                final URL file,
+                                final Manifest manifest,
+                                final int startLevel) throws IOException  {
         super(a.getId().toMvnId());
         this.artifact = a;
-        this.artifactFile = file;
         this.startLevel = startLevel;
-        try (final JarFile jarFile = IOUtils.getJarFileFromURL(this.artifactFile, true, null)) {
-            this.manifest = jarFile.getManifest();
-        }
-        if ( this.manifest == null ) {
+        this.artifactFile = file;
+        if ( manifest == null ) {
             throw new IOException("File has no manifest");
         }
+        this.manifest = new Manifest(manifest);
+
         this.analyze();
         this.lock();
     }
diff --git a/src/test/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImplTest.java b/src/test/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImplTest.java
index 1bdc342..c56d9c3 100644
--- a/src/test/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImplTest.java
+++ b/src/test/java/org/apache/sling/feature/scanner/impl/BundleDescriptorImplTest.java
@@ -16,13 +16,7 @@
  */
 package org.apache.sling.feature.scanner.impl;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
+import java.io.*;
 import java.net.URL;
 import java.util.Set;
 import java.util.jar.JarOutputStream;
@@ -30,10 +24,16 @@ import java.util.jar.Manifest;
 
 import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.ArtifactId;
+import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.io.json.FeatureJSONReader;
+import org.apache.sling.feature.scanner.FeatureDescriptor;
 import org.apache.sling.feature.scanner.PackageInfo;
+import org.apache.sling.feature.scanner.Scanner;
 import org.junit.Test;
 import org.osgi.framework.Version;
 
+import static org.junit.Assert.*;
+
 public class BundleDescriptorImplTest
 {
 
@@ -61,6 +61,18 @@ public class BundleDescriptorImplTest
         assertPackageInfo(infos,"org.apache.felix", Version.parseVersion("2.0"));
     }
 
+    @Test
+    public void testBundleManifest() throws Exception {
+        Feature feature = FeatureJSONReader.read(new InputStreamReader(getClass().getResourceAsStream("/metadata-feature.json")), null);
+        Scanner scanner = new Scanner(artifactId -> null);
+        FeatureDescriptor descriptor = scanner.scan(feature);
+        assertEquals(feature.getBundles().size(), descriptor.getBundleDescriptors().size());
+        assertNull(descriptor.getBundleDescriptors().iterator().next().getArtifactFile());
+        assertEquals("2.0", descriptor.getBundleDescriptors().stream()
+                .filter(b -> b.getBundleSymbolicName().equals("log4j.over.slf4j")).findFirst().get()
+                .getManifest().getMainAttributes().getValue("Manifest-Version"));
+    }
+
     private File createBundle(String manifest) throws IOException
     {
         File f = File.createTempFile("bundle", ".jar");
diff --git a/src/test/resources/metadata-feature.json b/src/test/resources/metadata-feature.json
new file mode 100644
index 0000000..f0aa623
--- /dev/null
+++ b/src/test/resources/metadata-feature.json
@@ -0,0 +1,76 @@
+{
+  "id": "org.acme:acmefeature:slingosgifeature:metadata-feature:0.0.1",
+  "bundles": [
+    "org.slf4j:jcl-over-slf4j:1.7.25",
+    "org.slf4j:log4j-over-slf4j:1.7.25",
+    "org.slf4j:slf4j-api:1.7.25"
+  ],
+  "analyser-metadata:JSON|false": {
+    "org.slf4j:jcl-over-slf4j:1.7.25": {
+      "manifest" : {
+        "Manifest-Version": "1.0",
+        "Archiver-Version": "Plexus Archiver",
+        "Created-By": "Apache Maven",
+        "Built-By": "ceki",
+        "Build-Jdk": "1.7.0_17",
+        "Bundle-Description": "JCL 1.2 implemented over SLF4J",
+        "Bundle-Version": "1.7.25",
+        "Implementation-Version": "1.7.25",
+        "X-Compile-Source-JDK": "1.5",
+        "X-Compile-Target-JDK": "1.5",
+        "Implementation-Title": "jcl-over-slf4j",
+        "Bundle-ManifestVersion": "2",
+        "Bundle-SymbolicName": "jcl.over.slf4j",
+        "Bundle-Name": "jcl-over-slf4j",
+        "Bundle-Vendor": "SLF4J.ORG",
+        "Bundle-RequiredExecutionEnvironment": "J2SE-1.5",
+        "Export-Package": "org.apache.commons.logging;version=1.2,  org.apache.commons.logging.impl;version=1.2",
+        "Import-Package": "org.slf4j;version=1.7.25, org.slf4j.spi;version=1.7.25"
+      }
+    },
+    "org.slf4j:log4j-over-slf4j:1.7.25": {
+      "manifest" : {
+        "Manifest-Version": "2.0",
+        "Archiver-Version": "Plexus Archiver",
+        "Created-By": "Apache Maven",
+        "Built-By": "ceki",
+        "Build-Jdk": "1.7.0_17",
+        "Bundle-Description": "Log4j implemented over SLF4J",
+        "Bundle-Version": "1.7.25",
+        "Implementation-Version": "1.7.25",
+        "X-Compile-Source-JDK": "1.5",
+        "X-Compile-Target-JDK": "1.5",
+        "Implementation-Title": "log4j-over-slf4j",
+        "Bundle-ManifestVersion": "2",
+        "Bundle-SymbolicName": "log4j.over.slf4j",
+        "Bundle-Name": "log4j-over-slf4j",
+        "Bundle-Vendor": "SLF4J.ORG",
+        "Bundle-RequiredExecutionEnvironment": "J2SE-1.5",
+        "Export-Package": "org.apache.log4j;version=1.2.17,org.apache.log4j.helpers;version=1.2.17,org.apache.log4j.spi;version=1.2.17,org.apache.log4j.xml;version=1.2.17",
+        "Import-Package": "org.slf4j;version=1.6.0,org.slf4j.helpers;version=1.6.0,org.slf4j.spi;version=1.6.0"
+      }
+    },
+    "org.slf4j:slf4j-api:1.7.25": {
+      "manifest" : {
+        "Manifest-Version": "1.0",
+        "Archiver-Version": "Plexus Archiver",
+        "Created-By": "Apache Maven",
+        "Built-By": "ceki",
+        "Build-Jdk": "1.7.0_17",
+        "Bundle-Description": "The slf4j API",
+        "Bundle-Version": "1.7.25",
+        "Implementation-Version": "1.7.25",
+        "X-Compile-Source-JDK": "1.5",
+        "X-Compile-Target-JDK": "1.5",
+        "Implementation-Title": "slf4j-api",
+        "Bundle-ManifestVersion": "2",
+        "Bundle-SymbolicName": "slf4j.api",
+        "Bundle-Name": "slf4j-api",
+        "Bundle-Vendor": "SLF4J.ORG",
+        "Bundle-RequiredExecutionEnvironment": "J2SE-1.5",
+        "Export-Package": "org.slf4j;version=1.7.25, org.slf4j.spi;version=1.7.25, org.slf4j.helpers;version=1.7.25, org.slf4j.event;version=1.7.25",
+        "Import-Package": "org.slf4j.impl;version=1.6.0"
+      }
+    }
+  }
+}
\ No newline at end of file