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