private Set bootStage()

in profile/src/main/java/org/apache/karaf/profile/assembly/Builder.java [1745:1931]


    private Set<Feature> bootStage(Profile bootProfile, Profile startupEffective, FeaturesProcessor processor) throws Exception {
        LOGGER.info("Boot stage");
        //
        // Handle boot profiles
        //
        Profile bootOverlay = Profiles.getOverlay(bootProfile, allProfiles, environment);
        Profile bootEffective = Profiles.getEffective(bootOverlay, false);
        // Load startup repositories
        LOGGER.info("   Loading boot repositories");
        Map<String, Features> bootRepositories = loadRepositories(manager, bootEffective.getRepositories(), true, processor);
        // Compute startup feature dependencies
        Set<Feature> allBootFeatures = new HashSet<>();
        for (Features repo : bootRepositories.values()) {
            allBootFeatures.addAll(repo.getFeature());
        }
        // Generate a global feature
        Map<String, Dependency> generatedDep = new HashMap<>();
        generatedBootFeatureName = UUID.randomUUID().toString();
        Feature generated = new Feature();
        generated.setName(generatedBootFeatureName);
        // Add feature dependencies
        for (String nameOrPattern : bootEffective.getFeatures()) {
            // KARAF-5273: feature may be a pattern
            for (String dependency : FeatureSelector.getMatchingFeatures(nameOrPattern, bootRepositories.values())) {
                Dependency dep = generatedDep.get(dependency);
                if (dep == null) {
                    dep = createDependency(dependency);
                    generated.getFeature().add(dep);
                    generatedDep.put(dep.getName(), dep);
                }
                dep.setDependency(false);
                dep.setPrerequisite(firstStageBootFeatures.contains(dep.getName()) || firstStageBootFeatures.contains(
                        nameOrPattern));
            }
        }
        // Add bundles
        for (String location : bootEffective.getBundles()) {
            location = location.replace("profile:", "file:etc/");
            int intLevel = -100;
            if (location.contains(START_LEVEL)) {
                //extract start-level for this bundle
                String level = location.substring(location.indexOf(START_LEVEL));
                level = level.substring(START_LEVEL.length() + 1);
                if (level.startsWith("\"")) {
                    level = level.substring(1, level.length() - 1);
                }
                intLevel = Integer.parseInt(level);
                LOGGER.debug("bundle start-level: " + level);
                location = location.substring(0, location.indexOf(START_LEVEL) - 1);
                LOGGER.debug("new bundle location after strip start-level: " + location);
            }
            Bundle bun = new Bundle();
            if (intLevel > 0) {
                bun.setStartLevel(intLevel);
            }
            bun.setLocation(location);
            generated.getBundle().add(bun);
        }
        Features rep = new Features();
        rep.setName(UUID.randomUUID().toString());
        rep.getRepository().addAll(bootEffective.getRepositories());
        rep.getFeature().add(generated);
        allBootFeatures.add(generated);

        Downloader downloader = manager.createDownloader();

        // Compute startup feature dependencies
        FeatureSelector selector = new FeatureSelector(allBootFeatures);
        Set<Feature> bootFeatures = selector.getMatching(singletonList(generated.getName()));
        for (Feature feature : bootFeatures) {
            if (feature.isBlacklisted()) {
                LOGGER.info("   Feature " + feature.getId() + " is blacklisted, ignoring");
                continue;
            }
            LOGGER.info("   Feature " + feature.getId() + " is defined as a boot feature");
            // add the feature in the system folder
            Set<BundleInfo> bundleInfos = new HashSet<>();
            for (Bundle bundle : feature.getBundle()) {
                if (!ignoreDependencyFlag || !bundle.isDependency()) {
                    bundleInfos.add(bundle);
                }
            }
            for (Conditional cond : feature.getConditional()) {
                if (cond.isBlacklisted()) {
                    LOGGER.info("   Conditionial " + cond.getConditionId() + " is blacklisted, ignoring");
                }
                for (Bundle bundle : cond.getBundle()) {
                    if (!ignoreDependencyFlag || !bundle.isDependency()) {
                        bundleInfos.add(bundle);
                    }
                }
            }

            // Build optional features and known prerequisites
            Map<String, List<String>> prereqs = new HashMap<>();
            prereqs.put("blueprint:", Arrays.asList("deployer", "aries-blueprint"));
            prereqs.put("spring:", Arrays.asList("deployer", "spring"));
            prereqs.put("wrap:", Collections.singletonList("wrap"));
            prereqs.put("war:", Collections.singletonList("war"));
            ArtifactInstaller installer = new ArtifactInstaller(systemDirectory, downloader, blacklist);
            for (BundleInfo bundleInfo : bundleInfos) {
                installer.installArtifact(bundleInfo);
                for (Map.Entry<String, List<String>> entry : prereqs.entrySet()) {
                    if (bundleInfo.getLocation().trim().startsWith(entry.getKey())) {
                        for (String prereq : entry.getValue()) {
                            Dependency dep = generatedDep.get(prereq);
                            if (dep == null) {
                                dep = new Dependency();
                                dep.setName(prereq);
                                generated.getFeature().add(dep);
                                generatedDep.put(dep.getName(), dep);
                            }
                            dep.setPrerequisite(true);
                        }
                    }
                }
            }

            new ConfigInstaller(etcDirectory, pidsToExtract)
                .installConfigs(feature, downloader, installer);
            // Install libraries
            List<String> libraries = new ArrayList<>();
            for (Library library : feature.getLibraries()) {
                String lib = library.getLocation() +
                        ";type:=" + library.getType() +
                        ";export:=" + library.isExport() +
                        ";delegate:=" + library.isDelegate();
                libraries.add(lib);
            }
            Path configPropertiesPath = etcDirectory.resolve("config.properties");
            Properties configProperties = new Properties(configPropertiesPath.toFile());
            downloadLibraries(downloader, configProperties, libraries, "   ");
            downloader.await();
            // Reformat clauses
            reformatClauses(configProperties, Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA);
            reformatClauses(configProperties, Constants.FRAMEWORK_BOOTDELEGATION);
            configProperties.save();
        }

        // If there are bundles to install, we can't use the boot features only
        // so keep the generated feature
        Path featuresCfgFile = etcDirectory.resolve("org.apache.karaf.features.cfg");
        if (!generated.getBundle().isEmpty()) {
            File output = etcDirectory.resolve(rep.getName() + ".xml").toFile();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            JaxbUtil.marshal(rep, baos);
            ByteArrayInputStream bais;
            String repoUrl;
            if (karafVersion == KarafVersion.v24) {
                String str = baos.toString();
                str = str.replace("http://karaf.apache.org/xmlns/features/v1.3.0", "http://karaf.apache.org/xmlns/features/v1.2.0");
                str = str.replaceAll(" dependency=\".*?\"", "");
                str = str.replaceAll(" prerequisite=\".*?\"", "");
                for (Feature f : rep.getFeature()) {
                    for (Dependency d : f.getFeature()) {
                        if (d.isPrerequisite()) {
                            if (!startupEffective.getFeatures().contains(d.getName())) {
                                LOGGER.warn("Feature " + d.getName() + " is a prerequisite and should be installed as a startup feature.");                }
                        }
                    }
                }
                bais = new ByteArrayInputStream(str.getBytes());
                repoUrl = "file:etc/" + output.getName();
            } else {
                bais = new ByteArrayInputStream(baos.toByteArray());
                repoUrl = "file:${karaf.etc}/" + output.getName();
            }
            Files.copy(bais, output.toPath());
            Properties featuresProperties = new Properties(featuresCfgFile.toFile());
            featuresProperties.put(FEATURES_REPOSITORIES, repoUrl);
            featuresProperties.put(FEATURES_BOOT, generated.getName());
            featuresProperties.save();
        }
        else {
            String repos = getRepos(rep);
            String boot = getBootFeatures(generatedDep);

            Properties featuresProperties = new Properties(featuresCfgFile.toFile());
            featuresProperties.put(FEATURES_REPOSITORIES, repos);
            featuresProperties.put(FEATURES_BOOT, boot);
            reformatClauses(featuresProperties, FEATURES_REPOSITORIES);
            reformatClauses(featuresProperties, FEATURES_BOOT);
            featuresProperties.save();
        }
        downloader.await();
        return allBootFeatures;
    }