in src/main/java/org/apache/sling/feature/builder/BuilderUtil.java [655:714]
static void mergeExtensions(final Feature target,
final Feature source,
final BuilderContext context,
final List<ArtifactId> artifactOverrides,
final String originKey,
final boolean prototypeMerge,
final boolean initialMerge) {
for(final Extension ext : source.getExtensions()) {
boolean found = false;
// Make a defensive copy of the extensions, as the handlers may modify the extensions on the target
for(final Extension current : new ArrayList<>(target.getExtensions())) {
if ( current.getName().equals(ext.getName()) ) {
found = true;
if ( current.getType() != ext.getType() ) {
throw new IllegalStateException("Found different types for extension " + current.getName()
+ " : " + current.getType() + " and " + ext.getType());
}
boolean handled = false;
for(final MergeHandler me : context.getMergeExtensions()) {
if ( me.canMerge(current) ) {
me.merge(new HandlerContextImpl(context, me, prototypeMerge, initialMerge), target, source, current, ext);
handled = true;
break;
}
}
if ( !handled ) {
// default merge
mergeExtensions(current, ext, source, artifactOverrides, originKey);
}
}
}
if ( !found ) {
// The extension isn't found in the target, still call merge to allow handlers to operate on the
// first extension being aggregated
boolean handled = false;
for (final MergeHandler mh : context.getMergeExtensions()) {
if (mh.canMerge(ext)) {
mh.merge(new HandlerContextImpl(context, mh, prototypeMerge, initialMerge), target, source, null, ext);
handled = true;
break;
}
}
if ( !handled ) {
// no merge handler, just merge with an empty target
Extension current = new Extension(ext.getType(), ext.getName(), ext.getState());
target.getExtensions().add(current);
mergeExtensions(current, ext, source, artifactOverrides, originKey);
}
}
}
// post processing
// Make a defensive copy of the extensions, as the handlers may modify the extensions on the target
for(final Extension ext : new ArrayList<>(target.getExtensions())) {
for(final PostProcessHandler ppe : context.getPostProcessExtensions()) {
ppe.postProcess(new HandlerContextImpl(context, ppe, prototypeMerge, initialMerge), target, ext);
}
}
}