private ContentPackageDescriptorImpl extractContentPackage()

in src/main/java/org/apache/sling/feature/scanner/impl/ContentPackageScanner.java [152:286]


    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());
                                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);
        }
    }