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 09aecd2  SLING-9670: add a new unpack extension for the feature model.
09aecd2 is described below

commit 09aecd25ba87c4abe5a448c688fc18265eaf7481
Author: Karl Pauls <[email protected]>
AuthorDate: Tue Aug 18 17:01:37 2020 +0200

    SLING-9670: add a new unpack extension for the feature model.
---
 .../sling/feature/extension/unpack/Unpack.java     | 54 ++++++++++++++++++++--
 .../sling/feature/extension/unpack/TestUnpack.java | 36 ++++++++++++---
 .../sling/feature/extension/unpack/test1/index.txt |  1 -
 3 files changed, 79 insertions(+), 12 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 499660a..af8062c 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
@@ -35,12 +35,16 @@ import java.net.URL;
 import java.nio.file.FileAlreadyExistsException;
 import java.nio.file.Files;
 import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.function.BiConsumer;
 import java.util.jar.JarInputStream;
 import java.util.jar.Manifest;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 import java.util.zip.ZipEntry;
 
 public class Unpack
@@ -71,12 +75,14 @@ public class Unpack
                 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);
                 context.put("override", Boolean.toString(override));
                 context.put("key", key);
                 context.put("value", value);
+                context.put("index", index);
                 handler.accept(url, context);
             }
             return true;
@@ -141,18 +147,21 @@ public class Unpack
         {
             String dir = (String) context.get("dir");
             boolean override;
+            String index;
             if (dir == null && this.defaultMapping != null) {
                 dir = this.registry.get(defaultMapping).get("dir");
                 override = 
Boolean.parseBoolean(this.registry.get(defaultMapping).get("override"));
+                index = this.registry.get(defaultMapping).get("index");
             }
             else {
                 override = Boolean.parseBoolean((String) 
context.get("override"));
+                index = (String) context.get("index");
             }
 
             if (dir == null) {
                 throw new IllegalStateException("No target dir and no default 
configured");
             }
-            unpack(dir, stream, override);
+            unpack(dir, stream, override, index);
         } catch (IOException ex) {
             throw new UncheckedIOException(ex);
         }
@@ -164,6 +173,7 @@ public class Unpack
 
         // Syntax: 
system-fonts;dir:=abc;overwrite:=true,customer-fonts;dir:=eft;default:=true;key:=foobar;value:=baz
         Clause[] extClauses = Parser.parseHeader(mapping);
+
         for (Clause c : extClauses) {
             Map<String,String> cfg = new HashMap<>();
 
@@ -175,18 +185,29 @@ public class Unpack
         return new Unpack(registry);
     }
 
-    private void unpack(String dir, InputStream stream, boolean override) 
throws IOException {
+    private void unpack(String dir, InputStream stream, boolean override, 
String index) throws IOException {
         File base = new File(dir);
         if (!base.isDirectory() && !base.mkdirs()) {
             throw new IOException("Unable to find or created base dir: " + 
base);
         }
 
         try (JarInputStream jarInputStream = new JarInputStream(stream)) {
+            String indexValue = null;
+            if (index != null)
+            {
+                Manifest mf = jarInputStream.getManifest();
+                if (mf != null)
+                {
+                    indexValue = mf.getMainAttributes().getValue(index);
+                }
+            }
+
+            List<String> roots = parseRoots(indexValue);
             for (ZipEntry entry = jarInputStream.getNextEntry(); entry != 
null; entry = jarInputStream.getNextEntry())
             {
-                if (!entry.isDirectory() && 
!entry.getName().toLowerCase().startsWith("meta-inf/"))
+                if (!entry.isDirectory() && isRoot(roots, entry.getName()))
                 {
-                    File target = new File(base, entry.getName());
+                    File target = new File(base, relativize(roots, 
entry.getName()));
                     if 
(target.getParentFile().toPath().startsWith(base.toPath()))
                     {
                         if (target.getParentFile().isDirectory() || 
target.getParentFile().mkdirs())
@@ -220,4 +241,29 @@ public class Unpack
             }
         }
     }
+
+    private boolean isRoot(List<String> roots, String path) {
+        return roots.stream().anyMatch(root -> ("/" + path).startsWith(root));
+    }
+
+    private List<String> parseRoots(String index) {
+        List<String> roots = new ArrayList<>();
+
+        if (index != null) {
+            roots.addAll(Stream.of(Parser.parseDelimitedString(index, 
",")).map(root -> root.endsWith("/") ? root : root + "/").map(root -> 
root.startsWith("/") ? root : "/" + root).collect(Collectors.toList()));
+        }
+        else {
+            roots.add("/");
+        }
+        return roots;
+    }
+
+    private String relativize(List<String> roots, String path) {
+        for (String root : roots) {
+            if (("/" + path).startsWith(root)) {
+                return path.substring(root.length() -1);
+            }
+        }
+        throw new IllegalStateException("Can't find a root for: " + path);
+    }
 }
diff --git 
a/featuremodel-unpack-extension/src/test/java/org/apache/sling/feature/extension/unpack/TestUnpack.java
 
b/featuremodel-unpack-extension/src/test/java/org/apache/sling/feature/extension/unpack/TestUnpack.java
index 8e25309..933168c 100644
--- 
a/featuremodel-unpack-extension/src/test/java/org/apache/sling/feature/extension/unpack/TestUnpack.java
+++ 
b/featuremodel-unpack-extension/src/test/java/org/apache/sling/feature/extension/unpack/TestUnpack.java
@@ -25,7 +25,11 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.net.URL;
+import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 import java.util.jar.JarFile;
 import java.util.jar.JarOutputStream;
 import java.util.jar.Manifest;
@@ -42,26 +46,39 @@ public class TestUnpack
     {
         File tmp = File.createTempFile("foo", "dir");
         tmp.delete();
-        Unpack unpack = Unpack.fromMapping("test;default:=true;dir:=\"" + 
tmp.getPath() + "\"");
+        Unpack unpack = Unpack.fromMapping("test;default:=true;dir:=\"" + 
tmp.getPath() + "\";index:=\"Unpack-Index\";key:=binary;value:=1");
         URL url = createZipFile("test1");
 
         unpack.unpack(url.openStream(), Collections.emptyMap());
 
-        Assert.assertTrue(equals("test1", url));
+        Assert.assertTrue(equals("test1", tmp));
     }
 
+    private List<String> childs(File file, String prefix) {
+        List<String> result = new ArrayList<>();
+        for (File child : file.listFiles()) {
+            if (child.isDirectory()) {
+                result.addAll(childs(child, prefix + "/" + child.getName()));
+            }
+            else {
+                result.add(prefix + "/" + child.getName());
+            }
+        }
+        return result;
+    }
     private URL createZipFile(String base) throws IOException {
         File tmp = File.createTempFile("foo", ".zip");
         tmp.deleteOnExit();
         Manifest mf = new Manifest();
         mf.getMainAttributes().putValue("Manifest-Version", "1");
         mf.getMainAttributes().putValue("binary", "1");
+        mf.getMainAttributes().putValue("Unpack-Index", "sub1,sub2");
         try (JarOutputStream jarOutputStream = new JarOutputStream(new 
FileOutputStream(tmp), mf);
              BufferedReader reader = new BufferedReader(new 
InputStreamReader(TestUnpack.class.getResourceAsStream(base + "/index.txt"), 
"UTF-8")))
         {
             for (String line = reader.readLine(); line != null; line = 
reader.readLine())
             {
-                jarOutputStream.putNextEntry(new ZipEntry(line));
+                jarOutputStream.putNextEntry(new 
ZipEntry(line.contains("sub1") ? "sub1/" + line : line.contains("sub2") ? 
"sub2/" + line : line ));
                 try (InputStream inputStream = 
TestUnpack.class.getResourceAsStream(base + "/" + line)) {
                     byte[] buffer = new byte[64 * 1024];
                     for (int i = inputStream.read(buffer); i != -1; i = 
inputStream.read(buffer)) {
@@ -73,14 +90,19 @@ public class TestUnpack
         return tmp.toURI().toURL();
     }
 
-    private boolean equals(String base, URL jar) throws IOException {
-        try (JarFile jarFile = IOUtils.getJarFileFromURL(jar, false, null);
-             BufferedReader reader = new BufferedReader(new 
InputStreamReader(TestUnpack.class.getResourceAsStream(base + "/index.txt"), 
"UTF-8"))) {
+    private boolean equals(String base, File file) throws IOException {
+        try (BufferedReader reader = new BufferedReader(new 
InputStreamReader(TestUnpack.class.getResourceAsStream(base + "/index.txt"), 
"UTF-8"))) {
+            Set<String> content = new HashSet<>();
+            List<String> childs = childs(file, "");
             for (String line = reader.readLine(); line != null; line = 
reader.readLine())
             {
-                if (jarFile.getEntry(line)==null) {
+                if (!childs.contains("/" + line)) {
                     return false;
                 }
+                content.add(line);
+            }
+            if (childs.stream().anyMatch(entry -> 
!content.contains(entry.substring(1)))) {
+                return false;
             }
         }
         return true;
diff --git 
a/featuremodel-unpack-extension/src/test/resources/org/apache/sling/feature/extension/unpack/test1/index.txt
 
b/featuremodel-unpack-extension/src/test/resources/org/apache/sling/feature/extension/unpack/test1/index.txt
index 819a62a..af44720 100644
--- 
a/featuremodel-unpack-extension/src/test/resources/org/apache/sling/feature/extension/unpack/test1/index.txt
+++ 
b/featuremodel-unpack-extension/src/test/resources/org/apache/sling/feature/extension/unpack/test1/index.txt
@@ -1,4 +1,3 @@
-test.txt
 sub1/test1.txt
 sub2/test1.txt
 sub2/test2.txt
\ No newline at end of file

Reply via email to