SLING-9258 : Provide features to consumer when reading feature archive
diff --git a/pom.xml b/pom.xml
index 6fa1ac4..21d2557 100644
--- a/pom.xml
+++ b/pom.xml
@@ -162,7 +162,7 @@
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
- <version>2.8.9</version>
+ <version>3.3.3</version>
<scope>test</scope>
</dependency>
<dependency>
diff --git a/src/main/java/org/apache/sling/feature/io/archive/ArchiveReader.java b/src/main/java/org/apache/sling/feature/io/archive/ArchiveReader.java
index 6bbad77..af7b404 100644
--- a/src/main/java/org/apache/sling/feature/io/archive/ArchiveReader.java
+++ b/src/main/java/org/apache/sling/feature/io/archive/ArchiveReader.java
@@ -16,9 +16,14 @@
*/
package org.apache.sling.feature.io.archive;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
@@ -60,9 +65,9 @@
* caller to close the input stream.
*
* @param in The input stream to read from.
- * @param consumer The plugin consuming the binaries, if {@code null} only the
- * feature models are read
- * @return The feature models
+ * @param consumer The plugin consuming the binaries, including the features.
+ * If no consumer is provided, only the features will be returned.
+ * @return The feature models mentioned in the manifest of the archive
* @throws IOException If anything goes wrong
*/
public static Set<Feature> read(final InputStream in,
@@ -83,10 +88,35 @@
JarEntry entry = null;
while ( ( entry = jis.getNextJarEntry() ) != null ) {
if (!entry.isDirectory() && !entry.getName().startsWith("META-INF/")) {
- if (featurePaths.contains(entry.getName())) { // feature
- features.add(FeatureJSONReader.read(new InputStreamReader(jis, "UTF-8"), entry.getName()));
- } else { // artifact
- final ArtifactId id = ArtifactId.fromMvnPath(entry.getName());
+ final ArtifactId id = ArtifactId.fromMvnPath(entry.getName());
+
+ if (featurePaths.contains(entry.getName())) {
+ // feature - read to string first
+ final String contents;
+ try ( final StringWriter writer = new StringWriter()) {
+ // don't close the input stream
+ final Reader reader = new InputStreamReader(jis, "UTF-8");
+ final char[] buffer = new char[2048];
+ int l;
+ while ( (l = reader.read(buffer)) > 0) {
+ writer.write(buffer, 0, l);
+ }
+ writer.flush();
+ contents = writer.toString();
+ }
+ // add to features
+ try ( final Reader reader = new StringReader(contents) ) {
+ final Feature feature = FeatureJSONReader.read(reader, entry.getName());
+ features.add(feature);
+ }
+ // pass to consumer
+ if ( consumer != null ) {
+ try ( final InputStream is = new ByteArrayInputStream(contents.getBytes(StandardCharsets.UTF_8))) {
+ consumer.consume(id, is);
+ }
+ }
+ } else {
+ // artifact
if (consumer != null) {
consumer.consume(id, jis);
}
diff --git a/src/test/java/org/apache/sling/feature/io/archive/ArchiveWriterTest.java b/src/test/java/org/apache/sling/feature/io/archive/ArchiveWriterTest.java
index cfd09f1..ee3fa71 100644
--- a/src/test/java/org/apache/sling/feature/io/archive/ArchiveWriterTest.java
+++ b/src/test/java/org/apache/sling/feature/io/archive/ArchiveWriterTest.java
@@ -26,6 +26,9 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -34,6 +37,7 @@
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.junit.Test;
public class ArchiveWriterTest {
@@ -65,16 +69,33 @@
}
final Set<ArtifactId> readIds = new HashSet<>();
+ final Set<ArtifactId> readFeatureIds = new HashSet<>();
+
final List<Feature> features = new ArrayList<>();
try (final InputStream in = new ByteArrayInputStream(archive)) {
features.addAll(ArchiveReader.read(in, (id, is) -> {
- readIds.add(id);
+
+ // read contents
byte[] read = readFromStream(is);
- assertEquals(artifactBytes.length, read.length);
- assertArrayEquals(artifactBytes, read);
+
+ // is feature?
+ if ( id.equals(f.getId()) ) {
+ try ( final Reader reader = new StringReader(new String(read, StandardCharsets.UTF_8))) {
+ final Feature readFeature = FeatureJSONReader.read(reader, id.toString());
+ assertEquals(f.getId(), readFeature.getId());
+ readFeatureIds.add(f.getId());
+ }
+ } else {
+ readIds.add(id);
+ assertEquals(artifactBytes.length, read.length);
+ assertArrayEquals(artifactBytes, read);
+ }
}));
}
+ assertEquals(1, readFeatureIds.size());
+ assertTrue(readFeatureIds.contains(f.getId()));
+
assertEquals(1, readIds.size());
assertTrue(readIds.contains(ArtifactId.parse("g:a:2")));