private ContentPackageDescriptorImpl extractContentPackage()

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