private static void convert()

in src/main/java/org/apache/sling/feature/modelconverter/FeatureToProvisioning.java [126:327]


    private static void convert(String provModelName, org.apache.sling.feature.Feature feature, String featureFileName,
            String outputFile,
            String[] runModes) {
        Feature provModel = new Feature(provModelName);

        final Map<String, Feature> additionalFeatures = new HashMap<>();

        if (runModes != null && runModes.length == 0) {
            runModes = null;
        }
        org.apache.sling.provisioning.model.KeyValueMap<String> vars = provModel.getVariables();
        for (Map.Entry<String, String> entry : feature.getVariables().entrySet()) {
            vars.put(entry.getKey(), entry.getValue());
        }

        Map<org.apache.sling.feature.Configuration, org.apache.sling.feature.Artifact> configBundleMap = new HashMap<>();

        // bundles
        for (final org.apache.sling.feature.Artifact bundle : feature.getBundles()) {
            final ArtifactId id = bundle.getId();
            final Artifact newBundle = new Artifact(id.getGroupId(), id.getArtifactId(), id.getVersion(), id.getClassifier(), id.getType());

            Object configs = bundle.getMetadata().get("configurations");
            if (configs instanceof List) {
                for (Object config : (List<?>) configs) {
                    if (config instanceof org.apache.sling.feature.Configuration) {
                        configBundleMap.put((org.apache.sling.feature.Configuration) config, bundle);
                    }
                }
            }

            for(final Map.Entry<String, String> prop : bundle.getMetadata().entrySet()) {
                switch (prop.getKey()) {
                    // these are handled separately
                    case "start-level":
                    case "run-modes":
                        break;
                    default:
                        newBundle.getMetadata().put(prop.getKey(), prop.getValue());
                }
            }

            String[] bundleRunModes = runModes;
            if (bundleRunModes == null) {
                bundleRunModes = getRunModes(bundle);
            }

            int startLevel = bundle.getStartOrder();

            String sl = bundle.getMetadata().get("start-level");
            // special handling for :boot or :launchpad
            if ( sl != null && sl.startsWith(":") ) {
                if ( bundleRunModes != null ) {
                    LOGGER.error(
                            "Unable to convert feature {}. Run modes must not be defined for bundles with start-level {}",
                            provModel.getName(), sl);
                    System.exit(1);
                }

                Feature addFeat = additionalFeatures.get(sl);
                if ( addFeat == null ) {
                    addFeat = new Feature(sl);
                    additionalFeatures.put(sl, addFeat);
                }
                addFeat.getOrCreateRunMode(null).getOrCreateArtifactGroup(0).add(newBundle);
            } else {
                if (startLevel == 0) {
                    if (sl != null) {
                        startLevel = Integer.parseInt(sl);
                    } else {
                        startLevel = 20;
                    }
                }

                provModel.getOrCreateRunMode(bundleRunModes).getOrCreateArtifactGroup(startLevel).add(newBundle);
            }
        }

        // configurations
        for (final org.apache.sling.feature.Configuration cfg : feature.getConfigurations()) {
            final Configuration c;

            List<String> runModeList = new ArrayList<>();
            if (org.apache.sling.feature.Configuration.isFactoryConfiguration(cfg.getPid())) {
                String name = decodeRunModes(org.apache.sling.feature.Configuration.getName(cfg.getPid()), runModeList);
                c = new Configuration(name, org.apache.sling.feature.Configuration.getFactoryPid(cfg.getPid()));
            } else {
                String pid = decodeRunModes(cfg.getPid(), runModeList);
                c = new Configuration(pid, null);
            }
            final Enumeration<String> keys = cfg.getConfigurationProperties().keys();
            while ( keys.hasMoreElements() ) {
                String key = keys.nextElement();
                Object val = cfg.getProperties().get(key);

                if (key.startsWith("..")) {
                    key = ":" + key.substring(2);
                }
                c.getProperties().put(key, val);
            }
            String[] cfgRunModes = runModes;
            if (cfgRunModes == null) {
                cfgRunModes = runModeList.toArray(new String[] {});
                if (cfgRunModes.length == 0)
                    cfgRunModes = null;
            }
            provModel.getOrCreateRunMode(cfgRunModes).getConfigurations().add(c);
        }

        // framework properties
        for (final Map.Entry<String, String> prop : feature.getFrameworkProperties().entrySet()) {
            String key = prop.getKey();
            int idx = key.indexOf(".runmodes:");

            if (idx > 0) {
                String rm = key.substring(idx + ".runmodes:".length());
                String[] runmodes = rm.split(",");
                key = key.substring(0, idx);
                provModel.getOrCreateRunMode(runmodes).getSettings().put(key, prop.getValue());
            } else {
                provModel.getOrCreateRunMode(null).getSettings().put(key, prop.getValue());
            }
        }

        // extensions: content packages and repoinit
        for (final Extension ext : feature.getExtensions()) {
            if (Extension.EXTENSION_NAME_CONTENT_PACKAGES.equals(ext.getName())) {
                for(final org.apache.sling.feature.Artifact cp : ext.getArtifacts() ) {
                    String[] extRunModes = runModes;
                    final ArtifactId id = cp.getId();
                    final Artifact newCP = new Artifact(id.getGroupId(), id.getArtifactId(), id.getVersion(), id.getClassifier(), id.getType());
                    for(final Map.Entry<String, String> prop : cp.getMetadata().entrySet()) {
                        if (prop.getKey().equals("runmodes")) {
                            if (extRunModes == null) {
                                extRunModes = prop.getValue().split(",");
                            }
                        } else {
                            newCP.getMetadata().put(prop.getKey(), prop.getValue());
                        }
                    }
                    provModel.getOrCreateRunMode(extRunModes).getOrCreateArtifactGroup(20).add(newCP);
                }

            } else if (Extension.EXTENSION_NAME_REPOINIT.equals(ext.getName())) {
                final String repoinitContents;
                if (ext.getType() == ExtensionType.TEXT) {
                    repoinitContents = ext.getText();
                } else if (ext.getType() == ExtensionType.JSON) {
                    JsonReader reader = Json.createReader(new StringReader(ext.getJSON()));
                    JsonArray arr = reader.readArray();
                    StringBuilder sb = new StringBuilder();
                    for (JsonValue v : arr) {
                        if (v instanceof JsonString) {
                            sb.append(((JsonString) v).getString());
                            sb.append('\n');
                        }
                    }
                    repoinitContents = sb.toString();
                } else {
                    repoinitContents = null;
                    LOGGER.error("Unable to convert repoinit extension with artifacts");
                    System.exit(1);
                }

                if (runModes == null) {
                    final Section section = new Section("repoinit");
                    section.setContents(repoinitContents);
                    provModel.getAdditionalSections().add(section);

                } else {
                    // create a factory configuration with repoinit
                    // create an name from the featureFileName
                    int lastDot = featureFileName.lastIndexOf('.');
                    String name = lastDot == -1 ? featureFileName : featureFileName.substring(0, lastDot);
                    name = name.replace('-', '_');

                    final RunMode runMode = provModel.getOrCreateRunMode(runModes);
                    final Configuration repoinitCfg = new Configuration(name,
                            "org.apache.sling.jcr.repoinit.RepositoryInitializer");
                    repoinitCfg.getProperties().put("scripts", repoinitContents);
                    runMode.getConfigurations().add(repoinitCfg);
                }
            } else if ( ext.getState() == ExtensionState.REQUIRED ) {
                LOGGER.error("Unable to convert required extension {}", ext.getName());
                System.exit(1);
            }
        }

        final String out = outputFile;
        final File file = new File(out);
        final Model m = new Model();
        m.getFeatures().add(provModel);
        for(final Feature addFeat : additionalFeatures.values()) {
            m.getFeatures().add(addFeat);
        }
        try ( final FileWriter writer = new FileWriter(file)) {
            ModelWriter.write(writer, m);
        } catch ( final IOException ioe) {
            LOGGER.error("Unable to write feature to {} : {}", out, ioe.getMessage(), ioe);
            System.exit(1);
        }
    }