Configuration Merger

What is the Configuration Merger?

The Configuration Merger can take two Configurations, a base and a layer. It will then merge the layer onto the base

Why not CascadingConfiguration?

There was a long thread on what the rules for cascading should be.

The CascadingConfiguration did not attempt to handle the specific case mentioned in the link above, which is namely the following situation:

          Layer: <a><b x="http://avalon.apache.org/excalibur/></a>
          Base: <a><b/></a>
          Result: <a><b x="http://avalon.apache.org/excalibur/><b/></a>
        
when using Configuration.getChild(name), CascadingConfiguration would do the right thing, but it didn't even attempt to when using Configuration.getChildren. We need a sane result from getChildren because we serialize the merged configurations when validating them. In the above example, the result expected should probably be the same as the layer.

Merging children in a deterministic manner

But how do we know that's what the user wants? We don't (at least I'm missing the ESP module for my computer). The answer? metadata

The ConfigurationMerger will use a specially named attribute, excalibur-configuration:merge, to control the merging of layer children with base children. For the example above, you will get the result above. But with the magic attribute on the layer:

          <a><b x="1" excalibur-configuration:merge="true"/></a>
        
the result will be:
          <a><b x="http://avalon.apache.org/excalibur/></a>
        

The excalibur-configuration:merge attribute is removed during the merge, since it metadata only needed to merge. Why is it removed? In case you are merging two configurations and then need to serialize the result for validation, you don't want merge metadata breaking that

A limitation is that there can only be a single child in both the layer and base with the same getName(). With complex configurations this could cause a problem.

What if there are multiple children with the same getName()

There is a solution. It is possible to define a key attibute using the magic attribute excalibur-configuration:key-attribute

When using a key attribute, the two items to merge must not only have the same name, they must also have the same value for the key attribute.

            Layer:
            <a>
              <b x="1" excalibur-configuration:merge="true" excalibur-configuration:key-attribute="x">
                <c>
              </b>
              <b x="http://avalon.apache.org/excalibur/>
            </a>

            Base:
            <a>
              <b x="http://avalon.apache.org/excalibur/>
              <b x="http://avalon.apache.org/excalibur/>
            </a>
          
Thus in order to merge <b x="http://avalon.apache.org/excalibur/>, the name must be the same and the x attribute must have the same value.

by Peter Royal