public static void merge()

in src/main/java/org/apache/sling/provisioning/model/MergeUtility.java [114:232]


    public static void merge(final Model base, final Model additional, final MergeOptions options) {
        // features
        for(final Feature feature : additional.getFeatures()) {
            final Feature baseFeature = base.getOrCreateFeature(feature.getName());

            // version check first
            boolean overwrite = false;
            if ( baseFeature.getVersion() != null ) {
                if ( feature.getVersion() == null ) {
                    continue;
                }
                final Version baseVersion = new Version(baseFeature.getVersion());
                final Version addVersion = new Version(feature.getVersion());
                if ( baseVersion.compareTo(addVersion) >= 0 ) {
                    continue;
                }
                overwrite = true;
            } else {
                if ( feature.getVersion() != null ) {
                    overwrite = true;
                }
            }
            if ( overwrite ) {
                // set version
                baseFeature.setVersion(feature.getVersion());
                // remove everything from base feature
                baseFeature.getRunModes().clear();
                baseFeature.getAdditionalSections().clear();
                baseFeature.getVariables().clear();
                baseFeature.setComment(null);
            }

            mergeComments(baseFeature, feature);
            baseFeature.setType(feature.getType());

            // additional sections (sections are not cloned, therefore comments do not need to be merged)
            baseFeature.getAdditionalSections().addAll(feature.getAdditionalSections());

            // variables
            baseFeature.getVariables().putAll(feature.getVariables());
            mergeComments(baseFeature.getVariables(), feature.getVariables());

            // run modes
            for(final RunMode runMode : feature.getRunModes()) {
                // check for special remove run mode
                final String names[] = runMode.getNames();
                if ( options.isHandleRemoveRunMode() && names != null ) {
                    if ( handleRemoveRunMode(baseFeature, runMode) ) {
                        continue;
                    }
                }
                final RunMode baseRunMode = baseFeature.getOrCreateRunMode(names);

                // artifact groups
                for(final ArtifactGroup group : runMode.getArtifactGroups()) {
                    final ArtifactGroup baseGroup = baseRunMode.getOrCreateArtifactGroup(group.getStartLevel());

                    mergeComments(baseGroup, group);

                    int foundStartLevel = 0;

                    for(final Artifact artifact : group) {
                        boolean addArtifact = true;
                        for(final ArtifactGroup searchGroup : baseRunMode.getArtifactGroups()) {
                            final Artifact found = searchGroup.search(artifact);
                            if ( found != null ) {
                                if ( options.isLatestArtifactWins() ) {
                                    searchGroup.remove(found);
                                    foundStartLevel = searchGroup.getStartLevel();
                                } else {
                                    try {
                                        final Version baseVersion = new Version(found.getVersion());
                                        final Version mergeVersion = new Version(artifact.getVersion());
                                        if ( baseVersion.compareTo(mergeVersion) <= 0 ) {
                                            searchGroup.remove(found);
                                            foundStartLevel = searchGroup.getStartLevel();
                                        } else {
                                            addArtifact = false;
                                        }
                                    } catch ( final IllegalArgumentException iae) {
                                        // if at least one version is not a valid maven version
                                        if ( found.getVersion().compareTo(artifact.getVersion()) <= 0 ) {
                                            searchGroup.remove(found);
                                            foundStartLevel = searchGroup.getStartLevel();
                                        } else {
                                            addArtifact = false;
                                        }
                                    }
                                }
                            }
                        }
                        if ( addArtifact ) {
                            // artifacts are not cloned, therefore comments do not need to be merged
                            if ( group.getStartLevel() == 0 && foundStartLevel != 0 ) {
                                baseRunMode.getOrCreateArtifactGroup(foundStartLevel).add(artifact);
                            } else {
                                baseGroup.add(artifact);
                            }
                        }
                    }
                }

                // configurations
                for(final Configuration config : runMode.getConfigurations()) {
                    final Configuration found = baseRunMode.getOrCreateConfiguration(config.getPid(), config.getFactoryPid());

                    mergeConfiguration(found, config);
                    mergeComments(found, config);
                }

                // settings
                for(final Map.Entry<String, String> entry : runMode.getSettings() ) {
                    baseRunMode.getSettings().put(entry.getKey(), entry.getValue());
                }
                mergeComments(baseRunMode.getSettings(), runMode.getSettings());
            }

        }
    }