in src/main/java/org/apache/sling/feature/scanner/impl/ContentPackageScanner.java [150:273]
private ContentPackageDescriptorImpl extractContentPackage(final ContentPackageDescriptorImpl parentPackage,
final String parentContentPath,
final Artifact packageArtifact,
final String name,
final URL archiveUrl,
final Set<ContentPackageDescriptorImpl> infos)
throws IOException {
logger.debug("Analyzing Content Package {}", archiveUrl);
final File tempDir = Files.createTempDirectory(null).toFile();
try {
final File toDir = new File(tempDir, archiveUrl.getPath().substring(archiveUrl.getPath().lastIndexOf("/") + 1));
toDir.mkdirs();
Manifest manifest = null;
final List<File> toProcess = new ArrayList<>();
final List<String> contentPaths = new ArrayList<>();
final List<BundleDescriptor> bundles = new ArrayList<>();
final List<Configuration> configs = new ArrayList<>();
final Properties packageProps = new Properties();
try (final JarFile zipFile = IOUtils.getJarFileFromURL(archiveUrl, true, null)) {
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
final ZipEntry entry = entries.nextElement();
final String entryName = entry.getName();
// skip dirs
if ( entryName.endsWith("/") ) {
continue;
}
logger.debug("Content package entry {}", entryName);
if ( entryName.startsWith("jcr_root/") ) {
final String contentPath = entryName.substring(8);
contentPaths.add(contentPath);
final FileType fileType = detectContentFileType(contentPath);
if (fileType != null) {
logger.debug("- extracting : {}", contentPath);
final File newFile = new File(toDir, entryName.replace('/', File.separatorChar));
newFile.getParentFile().mkdirs();
try (
final FileOutputStream fos = new FileOutputStream(newFile);
final InputStream zis = zipFile.getInputStream(entry);
) {
int len;
while ((len = zis.read(buffer)) > -1) {
fos.write(buffer, 0, len);
}
}
if (fileType == FileType.BUNDLE) {
int startLevel = 20;
final int lastSlash = contentPath.lastIndexOf('/');
final int nextSlash = contentPath.lastIndexOf('/', lastSlash - 1);
final String part = contentPath.substring(nextSlash + 1, lastSlash);
try {
startLevel = Integer.valueOf(part);
} catch (final NumberFormatException ignore) {
// ignore
}
final Artifact bundle = new Artifact(extractArtifactId(packageArtifact.getId(), newFile));
bundle.setStartOrder(startLevel);
final BundleDescriptor info = new BundleDescriptorImpl(bundle, newFile.toURI().toURL(),
startLevel);
bundle.getMetadata().put(ContentPackageDescriptorImpl.METADATA_PACKAGE,
packageArtifact.getId().toMvnId());
bundle.getMetadata().put(ContentPackageDescriptorImpl.METADATA_PATH, contentPath);
bundles.add(info);
} else if (fileType == FileType.CONFIG) {
final Configuration configEntry = this.processConfiguration(newFile, packageArtifact.getId(), contentPath);
if (configEntry != null) {
configs.add(configEntry);
}
} else if (fileType == FileType.PACKAGE) {
toProcess.add(newFile);
}
}
} else if ( FILE_MANIFEST.equals(entry.getName()) ) {
try ( final InputStream zis = zipFile.getInputStream(entry)) {
manifest = new Manifest(zis);
} catch ( final IOException ignore ) {
logger.warn("Failure reading manifest from {} : {}", packageArtifact.getId(), ignore.getMessage());
}
} else if ( FILE_PACKAGE_PROPS.equals(entry.getName()) ) {
try ( final InputStream zis = zipFile.getInputStream(entry)) {
packageProps.loadFromXML(zis);
}
}
}
final ContentPackageDescriptorImpl desc = new ContentPackageDescriptorImpl(name, packageArtifact, archiveUrl, manifest,
bundles, contentPaths, configs, packageProps);
if ( parentPackage != null ) {
desc.setParentContentPackageInfo(parentPackage, parentContentPath);
}
for (final File f : toProcess) {
final int lastDot = f.getName().lastIndexOf(".");
final String subName = f.getName().substring(0, lastDot);
final String contentPath = f.getAbsolutePath().substring(toDir.getAbsolutePath().length()).replace(File.separatorChar, '/');
// create synthetic artifact with a synthetic id containing the file name
final Artifact subArtifact = new Artifact(packageArtifact.getId().changeClassifier(subName));
extractContentPackage(desc, contentPath, subArtifact, subName, f.toURI().toURL(), infos);
}
infos.add(desc);
desc.lock();
return desc;
}
} finally {
deleteOnExitRecursive(tempDir);
}
}