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