in src/main/java/org/apache/sling/feature/io/archive/ArchiveReader.java [73:151]
public static Set<Feature> read(final InputStream in,
final ArtifactConsumer consumer)
throws IOException {
final JarInputStream jis = new JarInputStream(in);
// validate manifest and get feature ids
final String[] featureIds = checkHeaderAndExtractContents(jis.getManifest());
final List<String> featurePaths = Arrays.asList(featureIds).stream()
.map(id -> ArtifactId.parse(id).toMvnPath()).collect(Collectors.toList());
// read contents
final Set<Feature> features = new HashSet<>();
final Set<ArtifactId> artifacts = new HashSet<>();
JarEntry entry = null;
while ( ( entry = jis.getNextJarEntry() ) != null ) {
if (!entry.isDirectory() && !entry.getName().startsWith("META-INF/")) {
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);
}
artifacts.add(id);
}
}
jis.closeEntry();
}
if (features.isEmpty()) {
throw new IOException("Not a feature model archive - feature file is missing.");
}
// check whether all artifacts from the models are in the archive
for (final Feature feature : features) {
for (final Artifact a : feature.getBundles()) {
if (!artifacts.contains(a.getId())) {
throw new IOException("Artifact " + a.getId().toMvnId() + " is missing in archive");
}
}
for (final Extension e : feature.getExtensions()) {
if (e.getType() == ExtensionType.ARTIFACTS) {
for (final Artifact a : e.getArtifacts()) {
if (!artifacts.contains(a.getId())) {
throw new IOException("Artifact " + a.getId().toMvnId() + " is missing in archive");
}
}
}
}
}
return features;
}