After my last post I went away to play in the code for a while.
Mostly to see what is necessary to isolate a minmal set of classes related to Property handling.
What I found is:
1) Property is ubiquitous: every client class knows what package
it lives in. As a planning point, I better think about keeping
a Property class (or prepare to make a lot more changes and
lose a few friends).
2) PropertyList and PropertyListBuilder are used in fewer places.
but they are used a lot. PropertyList is referenced 129 times and PropertyListBuilder only 8 times. Most of these references are in the Property class. If they can be hidden, the problem
is bounded by the Property class.
In alt.design individual classes in fop.fo.properties extend fop.fo.Property, but these classes are singletons, providing access to what is effectively static information about the properties.
The multitude of property instances is represented by the interface fop.datatypes.PropertyValue, the abstract class AbstractPropertyValue and the class PropertyValueList, which implements PropertyValue, and the other classes in fop.datatypes which generally extend AbstractPropertyValue.
One way to discover the scope of an API is to rename a class or a package. Doing so breaks all of the compile units that depend on the renamed class(es). Restoring the missing interfaces restores the system if the restoration obeys the previous class contracts.
As I suspected, automated code generation for properties is do-able. There are more than 17,000 lines in files generated through Ant target: 'codegen'. Many of these are clients of the Property class. Changes here can be localized to the XSL files that generate the code.
The classes in fop.fo.properties (apart from Property.java itself) *could* be generated by XSLT. I used perl, one-off. If I need to make global changes, I'll use perl again. If I need to change, add or delete individual classes, I'll do it manually, based on a like-minded class if necessary. Should take about two minutes. How dramatically is the set of properties in XSL-FO going to change?
And now for a little digression on code generation. My own view of code generation by XSLT transformation can be summed up as:
* the canonical source is the Java code.
* transformations are a tool for developer convenience.
* they should be used to generate files which are then committed like any others.
* transformation is generally a one-off process, only to be re-used in extremis.
* it is the developer's responsibility to ensure that any re-generation does not lose patches to the previously generated and committed source.
Using this approach, the source you extract from CVS is the source you compile. If you apply a fix to that source, you know that it can go directly into the codebase.
An example is src/codegen/xml-lang.xml, which is transformed by src/codegen/xml-lang.xsl into org/apache/fop/datatypes/CountryLanguageScript.java. All that I could find about countries, languages and scripts is in xml-lang.xml. The result is checked-in to CVS, and will be part of the code base of any checkout. How often is this information going to change? Only if there are major changes to the information content of the relevant documents will the structure of the files need to be revisited, and it is no particular hardship to manage such cases.
Yes, there are situations in which it is *extremely* convenient to use code-munging - the Java 1.3/1.4 situation springs to mind. The CPP was extremely convenient too, for similar reasons. XSLT is much more powerful than CPP. Why is there no equivalent of CPP in Java? Why are we going to such trouble to create a situation which has even greater capacity for obfuscation that CPP? Because we're smarter than the developers of Java? Or because we have short memories?
Peter -- Peter B. West <http://www.powerup.com.au/~pbwest/resume.html>