The Apache Maven project model consists of a fairly rich model structure, consisting of 465 possible elements, specifying everything from the plugins Maven uses to build the project to the dependencies it needs for compiling. How Maven processes the model prior to a build can be a little confusing, dealing with the inheritance of parent poms (or the super pom), the applying of profiles, the merging in of dependency management information, to name just a few of the operations.
Back in May, Jason started talking to me about adding in mixin support for the pom, and it became clear that we needed to reconsider the Maven 2.0 design of project builder so that we could support such features. Maven 2.0 took the approach of merging trees of information (XML nodes), a perfectly reasonable approach for single inheritance. For things like mixins and multiple pom inheritance, linearizing the information proves a much simpler approach. In this post I discuss the ramifications of linearizing POM information to support multiple inheritance for POMs.
To linearize, of course, means that we have to flatten the XML nodes. I did this by creating a list of model properties, consisting of a URI and a value. So for example, the version would be modelProperty("http://apache.org/maven/project/version", "1.0"). The Maven 3.0 project builder creates a rather large list of model properties, stacking them, the child model properties being on top, while each of the parent model properties are placed lower in the list. Inheritance is now just a matter of sorting and removing model properties according to a set of rules.
To see how easy mixins is under linearized inheritance, let's say we have project A and project B, where project B is the child. Under single inheritance, Maven applies the sorting rules. For a mixin, we just place its model properties below project B's properties in the list and above those of project A. Maven applies the same sorting rules as single inheritance and doesn't care whether it's dealing with a parent model, a mixin or even a second parent model.
I've created a detailed specification of how Maven builds the project model, which I will be releasing shortly, giving all the precise rules Maven 3.0 follows for project construction.