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 <[email protected]>
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

Reply via email to