in src/main/java/org/apache/sling/feature/builder/BuilderUtil.java [70:108]
static void mergeVariables(final Feature targetFeature, final Feature sourceFeature, final Map<String,String> overrides) {
final Map<String,String> result = new LinkedHashMap<>();
final Map<String, Map<String, Object>> metadata = new HashMap<>();
// keep values from target features, no need to update origin
for (Map.Entry<String, String> entry : targetFeature.getVariables().entrySet()) {
result.put(entry.getKey(), overrides.containsKey(entry.getKey()) ? overrides.get(entry.getKey()) : entry.getValue());
metadata.put(entry.getKey(), targetFeature.getVariableMetadata(entry.getKey()));
}
// merge in from source feature
for (Map.Entry<String, String> entry : sourceFeature.getVariables().entrySet()) {
final List<ArtifactId> targetIds = (metadata.containsKey(entry.getKey())) ?
new ArrayList<>(targetFeature.getFeatureOrigins(metadata.get(entry.getKey()))) : new ArrayList<>();
targetIds.add(sourceFeature.getId());
if ( overrides.containsKey(entry.getKey()) ) {
result.put(entry.getKey(), overrides.get(entry.getKey()));
} else {
String value = entry.getValue();
if (value != null) {
String targetValue = targetFeature.getVariables().get(entry.getKey());
if (targetValue != null) {
if (!value.equals(targetValue)) {
throw new IllegalStateException(String.format("Can't merge variable '%s' defined twice (as '%s' v.s. '%s') and not overridden.", entry.getKey(), value, targetValue));
}
} else {
result.put(entry.getKey(), value);
}
} else if (!targetFeature.getVariables().containsKey(entry.getKey())) {
result.put(entry.getKey(), value);
}
}
metadata.put(entry.getKey(), new LinkedHashMap<>(sourceFeature.getVariableMetadata(entry.getKey())));
targetFeature.setFeatureOrigins(metadata.get(entry.getKey()), targetIds);
}
targetFeature.getVariables().clear();
targetFeature.getVariables().putAll(result);
for(final Map.Entry<String, Map<String, Object>> entry : metadata.entrySet()) {
targetFeature.getVariableMetadata(entry.getKey()).putAll(entry.getValue());
}
}