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

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


The following commit(s) were added to refs/heads/master by this push:
     new 9260f80  SLING-9670: add a new unpack extension for the feature model.
9260f80 is described below

commit 9260f803c7fcd8b56f62a06e2b71337e6ecc3614
Author: Karl Pauls <[email protected]>
AuthorDate: Mon Aug 24 18:32:45 2020 +0200

    SLING-9670: add a new unpack extension for the feature model.
---
 .../sling/feature/extension/unpack/Unpack.java     |  35 +++---
 .../extension/unpack/impl/converter/Converter.java | 101 ++++++++++++----
 .../unpack/impl/converter/ConverterTest.java       | 134 +++++++++++++++++++--
 3 files changed, 225 insertions(+), 45 deletions(-)

diff --git 
a/featuremodel-unpack-extension/src/main/java/org/apache/sling/feature/extension/unpack/Unpack.java
 
b/featuremodel-unpack-extension/src/main/java/org/apache/sling/feature/extension/unpack/Unpack.java
index 4ffe5df..5a7fb62 100644
--- 
a/featuremodel-unpack-extension/src/main/java/org/apache/sling/feature/extension/unpack/Unpack.java
+++ 
b/featuremodel-unpack-extension/src/main/java/org/apache/sling/feature/extension/unpack/Unpack.java
@@ -69,13 +69,13 @@ public class Unpack {
     public boolean handle(Extension extension, ArtifactProvider provider, 
BiConsumer<URL, Map<String, Object>> handler) {
         if (extension.getType() == ExtensionType.ARTIFACTS &&
             this.registry.containsKey(extension.getName())) {
+            String dir = this.registry.get(extension.getName()).get("dir");
+            boolean override = 
Boolean.parseBoolean(this.registry.get(extension.getName()).get("override"));
+            String key = this.registry.get(extension.getName()).get("key");
+            String value = this.registry.get(extension.getName()).get("value");
+            String index = this.registry.get(extension.getName()).get("index");
+
             for (Artifact artifact : extension.getArtifacts()) {
-                String dir = this.registry.get(extension.getName()).get("dir");
-                boolean override = 
Boolean.parseBoolean(this.registry.get(extension.getName()).get("override"));
-                URL url = provider.provide(artifact.getId());
-                String key = this.registry.get(extension.getName()).get("key");
-                String value = 
this.registry.get(extension.getName()).get("value");
-                String index = 
this.registry.get(extension.getName()).get("index");
                 Map<String, Object> context = new HashMap<>();
                 context.put("artifact.id", artifact.getId());
                 context.put("dir", dir);
@@ -83,6 +83,7 @@ public class Unpack {
                 context.put("key", key);
                 context.put("value", value);
                 context.put("index", index);
+                URL url = provider.provide(artifact.getId());
                 handler.accept(url, context);
             }
             return true;
@@ -108,14 +109,7 @@ public class Unpack {
         if (dir == null) {
             return false;
         } else if (key != null && value != null) {
-            try (JarInputStream jarInputStream = new JarInputStream(stream)) {
-                Manifest mf = jarInputStream.getManifest();
-                if (mf != null) {
-                    return 
value.equalsIgnoreCase(mf.getMainAttributes().getValue(key));
-                }
-            } catch (Exception ex) {
-                return false;
-            }
+            return handles(key, value, stream);
         } else if (contextDir != null) {
             return true;
         }
@@ -123,6 +117,19 @@ public class Unpack {
         return false;
     }
 
+    public static boolean handles(String key, String value, InputStream 
inputStream) {
+        try (JarInputStream jarInputStream = new JarInputStream(inputStream)) {
+            Manifest mf = jarInputStream.getManifest();
+            if (mf != null) {
+                return 
value.equalsIgnoreCase(mf.getMainAttributes().getValue(key));
+            } else {
+                return false;
+            }
+        } catch (Exception ex) {
+            return false;
+        }
+    }
+
 
     private void unpack(URL url, Map<String, Object> context) {
         try {
diff --git 
a/featuremodel-unpack-extension/src/main/java/org/apache/sling/feature/extension/unpack/impl/converter/Converter.java
 
b/featuremodel-unpack-extension/src/main/java/org/apache/sling/feature/extension/unpack/impl/converter/Converter.java
index 98f6257..0d7526f 100644
--- 
a/featuremodel-unpack-extension/src/main/java/org/apache/sling/feature/extension/unpack/impl/converter/Converter.java
+++ 
b/featuremodel-unpack-extension/src/main/java/org/apache/sling/feature/extension/unpack/impl/converter/Converter.java
@@ -19,8 +19,10 @@
 package org.apache.sling.feature.extension.unpack.impl.converter;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStreamWriter;
 import java.io.Writer;
 import java.net.URL;
@@ -29,6 +31,9 @@ import java.nio.file.Files;
 import java.nio.file.StandardCopyOption;
 import java.security.DigestInputStream;
 import java.security.MessageDigest;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Predicate;
 
 import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.ArtifactId;
@@ -36,43 +41,95 @@ import org.apache.sling.feature.Extension;
 import org.apache.sling.feature.ExtensionState;
 import org.apache.sling.feature.ExtensionType;
 import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.extension.unpack.Unpack;
 import org.apache.sling.feature.io.json.FeatureJSONWriter;
 
 public class Converter {
     public static void main(String[] args) throws Exception {
-        if (args.length > 1) {
-            File base = new File(args[0]);
+        if (args.length > 4) {
+            ArtifactId id = ArtifactId.fromMvnId(args[0]);
+
+            String name = args[1];
+            if (name == null || name.trim().isEmpty()) {
+                throw new IllegalStateException("Invalid extension name: " + 
name);
+            }
+
+            File featureFile = new File(args[2]);
+            if (!featureFile.getParentFile().isDirectory() && 
!featureFile.mkdirs()) {
+                throw new IOException("Unable to create target dir: " + 
featureFile.getParentFile());
+            }
+            File base = new File(args[3]);
             if (!base.isDirectory() && !base.mkdirs()) {
                 throw new IOException("Unable to create base dir: " + base);
             }
-            Feature feature = new Feature(new ArtifactId("cm", "cm-fonts", 
"0.0.1", null,  "slingosgifeature"));
-            Extension extension = new Extension(ExtensionType.ARTIFACTS, 
"user-fonts", ExtensionState.REQUIRED);
-            for (int i = 1; i < args.length; i++) {
-                String arg = args[i];
-                URL url = new URL(arg);
-                File tmp = File.createTempFile("fonts", ".zip");
-                try (DigestInputStream inputStream = new 
DigestInputStream(url.openStream(), MessageDigest.getInstance("SHA-512"))) {
-                    Files.copy(inputStream, tmp.toPath(), 
StandardCopyOption.REPLACE_EXISTING);
-                    String digest = 
bytesToHex(inputStream.getMessageDigest().digest());
-
-                    Artifact artifact = new Artifact(new ArtifactId("cm", 
"cm-fonts", "0.0.1", digest,  "zip"));
+
+            String key = null;
+            String value = null;
+
+            List<String> urls = new ArrayList<>();
+            for (int i = 4; i < args.length;i++) {
+                if (args[i].startsWith("key=")) {
+                    key = args[i].substring("key=".length());
+                } else if (args[i].startsWith("value=")) {
+                    value = args[i].substring("value=".length());
+                }
+                else{
+                    urls.add(args[i]);
+                }
+            }
+
+            Predicate<InputStream> check;
+            if (key != null && !key.trim().isEmpty() && value != null && 
!value.trim().isEmpty()) {
+                final String keyF = key;
+                final String valueF = value;
+                check = (stream) -> Unpack.handles(keyF, valueF, stream);
+            } else {
+                check = inputStream -> true;
+            }
+
+            List<String> unhandled = convert(id, name, featureFile, base, 
check, urls);
+
+            System.out.println(String.join(" ", unhandled));
+        }
+    }
+
+    public static List<String> convert(ArtifactId featureId, String 
extensionName, File featureFile, File repository, Predicate<InputStream> 
filter, List<String> urls) throws Exception {
+        Feature feature = new Feature(featureId);
+
+        List<String> unhandled = new ArrayList<>();
+
+        Extension extension = new Extension(ExtensionType.ARTIFACTS, 
extensionName, ExtensionState.REQUIRED);
+
+        for (String urlString : urls) {
+            URL url = new URL(urlString);
+            File tmp = File.createTempFile("unpack", ".zip");
+            try (DigestInputStream inputStream = new 
DigestInputStream(url.openStream(), MessageDigest.getInstance("SHA-512"))) {
+                Files.copy(inputStream, tmp.toPath(), 
StandardCopyOption.REPLACE_EXISTING);
+                String digest = 
bytesToHex(inputStream.getMessageDigest().digest());
+
+                if (filter.test(new FileInputStream(tmp))){
+                    Artifact artifact = new Artifact(new 
ArtifactId(featureId.getGroupId(), featureId.getArtifactId(), 
featureId.getVersion(), digest, "zip"));
                     extension.getArtifacts().add(artifact);
-                    File target = new File(base, artifact.getId().toMvnPath());
+                    File target = new File(repository, 
artifact.getId().toMvnPath());
                     if (!target.getParentFile().isDirectory() && 
!target.getParentFile().mkdirs()) {
                         throw new IOException("Unable to create parent dir: " 
+ target.getParentFile());
                     }
                     Files.move(tmp.toPath(), target.toPath(), 
StandardCopyOption.REPLACE_EXISTING);
+                } else {
+                    unhandled.add(urlString);
                 }
+            } finally {
+                tmp.delete();
             }
-            feature.getExtensions().add(extension);
-            File target = new File(base, feature.getId().toMvnPath());
-            if (!target.getParentFile().isDirectory() && 
!target.getParentFile().mkdirs()) {
-                throw new IOException("Unable to create parent dir: " + 
target.getParentFile());
-            }
-            try (Writer writer = new OutputStreamWriter(new 
FileOutputStream(target), StandardCharsets.UTF_8)) {
-                FeatureJSONWriter.write(writer, feature);
-            }
         }
+
+        feature.getExtensions().add(extension);
+
+        try (Writer writer = new OutputStreamWriter(new 
FileOutputStream(featureFile), StandardCharsets.UTF_8)) {
+            FeatureJSONWriter.write(writer, feature);
+        }
+
+        return unhandled;
     }
 
     private static final byte[] HEX_ARRAY = "0123456789ABCDEF".getBytes();
diff --git 
a/featuremodel-unpack-extension/src/test/java/org/apache/sling/feature/extension/unpack/impl/converter/ConverterTest.java
 
b/featuremodel-unpack-extension/src/test/java/org/apache/sling/feature/extension/unpack/impl/converter/ConverterTest.java
index 533f57a..d1ef209 100644
--- 
a/featuremodel-unpack-extension/src/test/java/org/apache/sling/feature/extension/unpack/impl/converter/ConverterTest.java
+++ 
b/featuremodel-unpack-extension/src/test/java/org/apache/sling/feature/extension/unpack/impl/converter/ConverterTest.java
@@ -19,35 +19,151 @@
 package org.apache.sling.feature.extension.unpack.impl.converter;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileOutputStream;
-import java.security.DigestOutputStream;
+import java.io.FileReader;
+import java.io.Reader;
+import java.security.DigestInputStream;
 import java.security.MessageDigest;
+import java.util.Arrays;
+import java.util.List;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
 
 import org.apache.sling.feature.ArtifactId;
+import org.apache.sling.feature.Extension;
+import org.apache.sling.feature.Feature;
+import org.apache.sling.feature.extension.unpack.Unpack;
+import org.apache.sling.feature.io.json.FeatureJSONReader;
 import org.junit.Assert;
 import org.junit.Test;
 
 public class ConverterTest
 {
     @Test
+    public void testConverterMain() throws Exception
+    {
+        File base = File.createTempFile("test", "unpack");
+        base.delete();
+        base.mkdirs();
+
+        File repo = new File(base, "repository");
+        File fontZip = new File(base, "unpack one-1.0.0 bar.zip");
+        File target = new File(base, "feature.json");
+        String digest;
+        Manifest mf = new Manifest();
+        mf.getMainAttributes().putValue("Manifest-Version", "1");
+        mf.getMainAttributes().putValue("FOO", "BAR");
+
+        try (JarOutputStream outputStream = new JarOutputStream(new 
FileOutputStream(fontZip), mf)) {
+        }
+        try (DigestInputStream inputStream = new DigestInputStream(new 
FileInputStream(fontZip), MessageDigest.getInstance("SHA-512"))) {
+            while (inputStream.read() != -1) {
+
+            }
+            digest = 
Converter.bytesToHex(inputStream.getMessageDigest().digest());
+        }
+
+        Converter.main(new 
String[]{"org.apache.sling:sling.unpack.test:slingosgifeature:0.0.1", "unpack", 
target.getPath(), repo.getPath(), "value=BAR", "key=FOO", 
fontZip.toURI().toURL().toString()});
+
+        Assert.assertTrue(target.isFile());
+
+        try (Reader reader = new FileReader(target)) {
+            Feature feature = FeatureJSONReader.read(reader, null);
+            
Assert.assertEquals(ArtifactId.fromMvnId("org.apache.sling:sling.unpack.test:slingosgifeature:0.0.1"),
 feature.getId());
+            Assert.assertFalse(feature.getExtensions().isEmpty());
+            Extension extension = feature.getExtensions().getByName("unpack");
+            Assert.assertNotNull(extension);
+            Assert.assertEquals(1, extension.getArtifacts().size());
+            
Assert.assertTrue(extension.getArtifacts().containsExact(ArtifactId.fromMvnId("org.apache.sling:sling.unpack.test:zip:"
 + digest + ":0.0.1")));
+        }
+
+        Assert.assertTrue(new File(repo, 
ArtifactId.fromMvnId("org.apache.sling:sling.unpack.test:zip:" + digest + 
":0.0.1").toMvnPath()).exists());
+    }
+
+    @Test
     public void testConverter() throws Exception
     {
-        File base = File.createTempFile("test", "fonts");
+        File base = File.createTempFile("test", "unpack");
         base.delete();
         base.mkdirs();
 
         File repo = new File(base, "repository");
-        File fontZip = new File(base, "fonts one-1.0.0 bar.zip");
+        File fontZip = new File(base, "unpack one-1.0.0 bar.zip");
+        File target = new File(base, "feature.json");
         String digest;
-        try (DigestOutputStream outputStream = new DigestOutputStream(new 
FileOutputStream(fontZip), MessageDigest.getInstance("SHA-512"))) {
-            outputStream.write(0xff);
-            digest = 
Converter.bytesToHex(outputStream.getMessageDigest().digest());
+        Manifest mf = new Manifest();
+        mf.getMainAttributes().putValue("Manifest-Version", "1");
+        mf.getMainAttributes().putValue("FOO", "BAR");
+
+        try (JarOutputStream outputStream = new JarOutputStream(new 
FileOutputStream(fontZip), mf)) {
+        }
+        try (DigestInputStream inputStream = new DigestInputStream(new 
FileInputStream(fontZip), MessageDigest.getInstance("SHA-512"))) {
+            while (inputStream.read() != -1) {
+
+            }
+            digest = 
Converter.bytesToHex(inputStream.getMessageDigest().digest());
         }
 
-        Converter.main(new String[]{repo.getPath(), 
fontZip.toURI().toURL().toString()});
+        List<String> unused = 
Converter.convert(ArtifactId.fromMvnId("org.apache.sling:sling.unpack.test:slingosgifeature:0.0.1"),
 "unpack", target, repo, (stream) -> Unpack.handles("FOO", "BAR", stream),  
Arrays.asList(fontZip.toURI().toURL().toString()));
 
-        Assert.assertTrue(new File(repo, 
ArtifactId.fromMvnId("cm:cm-fonts:slingosgifeature:0.0.1").toMvnPath()).exists());
+        Assert.assertTrue(target.isFile());
+        Assert.assertTrue(unused.isEmpty());
+
+        try (Reader reader = new FileReader(target)) {
+            Feature feature = FeatureJSONReader.read(reader, null);
+            
Assert.assertEquals(ArtifactId.fromMvnId("org.apache.sling:sling.unpack.test:slingosgifeature:0.0.1"),
 feature.getId());
+            Assert.assertFalse(feature.getExtensions().isEmpty());
+            Extension extension = feature.getExtensions().getByName("unpack");
+            Assert.assertNotNull(extension);
+            Assert.assertEquals(1, extension.getArtifacts().size());
+            
Assert.assertTrue(extension.getArtifacts().containsExact(ArtifactId.fromMvnId("org.apache.sling:sling.unpack.test:zip:"
 + digest + ":0.0.1")));
+        }
+
+        Assert.assertTrue(new File(repo, 
ArtifactId.fromMvnId("org.apache.sling:sling.unpack.test:zip:" + digest + 
":0.0.1").toMvnPath()).exists());
+    }
+
+    @Test
+    public void testConverterFilter() throws Exception
+    {
+        File base = File.createTempFile("test", "unpack");
+        base.delete();
+        base.mkdirs();
+
+        File repo = new File(base, "repository");
+        File fontZip = new File(base, "unpack one-1.0.0 bar.zip");
+        File target = new File(base, "feature.json");
+        String digest;
+        Manifest mf = new Manifest();
+        mf.getMainAttributes().putValue("Manifest-Version", "1");
+        mf.getMainAttributes().putValue("FOO", "BARs");
+
+        try (JarOutputStream outputStream = new JarOutputStream(new 
FileOutputStream(fontZip), mf)) {
+        }
+        try (DigestInputStream inputStream = new DigestInputStream(new 
FileInputStream(fontZip), MessageDigest.getInstance("SHA-512"))) {
+            while (inputStream.read() != -1) {
+
+            }
+            digest = 
Converter.bytesToHex(inputStream.getMessageDigest().digest());
+        }
+
+        List<String> unused = 
Converter.convert(ArtifactId.fromMvnId("org.apache.sling:sling.unpack.test:slingosgifeature:0.0.1"),
 "unpack", target, repo, (stream) -> Unpack.handles("FOO", "BAR", stream),  
Arrays.asList(fontZip.toURI().toURL().toString()));
+
+        Assert.assertTrue(target.isFile());
+        Assert.assertFalse(unused.isEmpty());
+
+        try (Reader reader = new FileReader(target)) {
+            Feature feature = FeatureJSONReader.read(reader, null);
+            
Assert.assertEquals(ArtifactId.fromMvnId("org.apache.sling:sling.unpack.test:slingosgifeature:0.0.1"),
 feature.getId());
+            Assert.assertFalse(feature.getExtensions().isEmpty());
+            Extension extension = feature.getExtensions().getByName("unpack");
+            Assert.assertNotNull(extension);
+            Assert.assertEquals(0, extension.getArtifacts().size());
+            
Assert.assertFalse(extension.getArtifacts().containsExact(ArtifactId.fromMvnId("org.apache.sling:sling.unpack.test:zip:"
 + digest + ":0.0.1")));
+        }
 
-        Assert.assertTrue(new File(repo, 
ArtifactId.fromMvnId("cm:cm-fonts:zip:" + digest + 
":0.0.1").toMvnPath()).exists());
+        Assert.assertFalse(new File(repo, 
ArtifactId.fromMvnId("org.apache.sling:sling.unpack.test:zip:" + digest + 
":0.0.1").toMvnPath()).exists());
+        Assert.assertTrue(unused.size() == 1);
+        Assert.assertEquals(fontZip.toURI().toURL().toString(),unused.get(0));
     }
 }

Reply via email to