The Danno / Dannotate codebase is split into a number of interdependent Maven modules. The structure is intended to foster reuse, and to allow us to separate Danno and Dannotate functionality for the case where the system integrator wants to deploy them separately.
The modules are as follows:
The project's parent POM file has three embedded properties:
The "danno-version" property is injected into the file "danno.common.webapp/src/main/resources/build.properties" using Maven resource filtering. Other build-time properties could potentially be injected there if there was a need to do this.
The siteTailoring.xml file is where the Spring beans that perform "simple property customizations" are configured. If you need to change the way that site-specific tailoring is implemented, this is file is the place to do it.
The file currently configures two beans to do apply the tailorings in "classes/*.properties" files to main Spring wirings:
The "poc" and "ppc" beans do their stuff on the bean descriptors after they have been read from the Spring wiring files, and before the descriptors are used to instantiate beans. The "order" properties of the "poc" and "ppc" beans specify that property overrides are applied first followed by the replacements.
One of the limitations of Spring 2.x wiring files is that there is no direct way expressing conditional wiring; e.g. "if property xyz is 'pqr', create this bean, otherwise that one.". However, we did discover and use one trick that works with Spring 2.5 wiring. For example:
<alias name="${tripleStore}TypeFactory" alias="typeFactory" />This defines the id "typeFactory" to be an alias for a bean whose name depends on the "tripleStore" replacement property. If we then declare lazily initialized beans called "sdbTypeFactory", "rdbTypeFactory" and so on, we can switch between different "typeFactory" beans by changing one property substitution parameter.
It is also possible to do more complicated things like this:
tripleStore=sdb
sdb.default.db=test
rdb.default.db=rtest
tripleStore.default.db=${${tripleStore}.default.db}However, for reasons that are not obvious, when you declare a bean "parent" using an alias, any placeholders in the alias values do not get substituted. This means that the alias switches won't work in conjunction with Spring property merging in a PropertyBeanFactory declaration. Fortunately, there is an (inelegant) alternative that works. A PropertyBeanFactory can be also be declared with an "array" of property objects, including references to property objects created elsewhere in the Spring wirings. The property object in the array are then merged by the PropertyBeanFactory.
In the previous section, we mentioned that you can implement conditional wiring using an <alias> element with placeholders in the "name" attribute. Another approach that you would imagine would work is this:
<import name="Danno-${tripleStore}.xml"/>However, this only works with standard Spring wiring if the parameters to be substituted are defined in the Java "system properties". This is unfortunate:
As a workaround, we use a (hacky) custom ContextLoaderListener that inserts properties from a configurable set of properties file into the system properties before starting the Spring wiring process. This works, modulo that it does not address point "2" above. A better solution may be to make more extensive changes to the Spring configuration codebase to get the placeholder expander used for <import> elements to get parameters from other places. But we are hoping that the Spring developers will do this work for us, as the changes look to be rather intrusive.