Re: Feedback on Processing Feedback
Hi Andreas, Jeremias, Andreas Delmelle wrote: snip/ [Vincent:] Using a TransformerFactory just to serialize data into an XML file may sound a bit weird (this has nothing to do with XSLT). It appears that Xerces defines an XMLSerializer class dedicated to that. snip / It's not weird at all, if you look at what is needed to serialize your data into a different format --possibly non-XML. Using the XMLSerializer, you would either: a) need a different sort of Serializer (properietary?) b) if the target is still XML, you /could/ add an XSLT step before the serialization Now, looking at it this way, why not simply use an identity Transformer to begin with. If your output target changes, all you need to do is write a stylesheet (which is much simpler than implementing your own Serializer), and alter one or two lines of Java code (some more if you also want the stylesheet to be pluggable). Thanks for the links and explanations. I tended to find the XMLSerializer idea quite elegant, but indeed this is not a very big deal to use TrAX (I guess the creation of the TransformerHandler can be encapsulated anyway), and also probably more flexible. Vincent -- Vincent HennebertAnyware Technologies http://people.apache.org/~vhennebert http://www.anyware-tech.com Apache FOP Committer FOP Development/Consulting
Re: Feedback on Processing Feedback
On Jan 31, 2008, at 08:50, Jeremias Maerki wrote: I'm not sure, yet, if it's so easily possible to get the TransformerFactory from the FopFactory as it's not available everywhere. This could take some additional wiring. At first I was simply thinking about a classloader-wide setting (i.e. static variable) plus a system property. After all, it's not just FOP that instantiates Transformers, but XML Graphics Commons and Batik, too. I'll look into it. Indeed. Sorry, I write that far too often: ...should 'simply'..., while it is not at all simple... Hey, maybe I should become a manager. ;-) I totally overlooked Commons and Batik. In that case, it could be worth considering moving this logic to Commons. In that case, if both Batik and FOP use it, the problem is solved for both. As indicated in the other thread about the XML APIs, not as a mandatory dependency that would also affect people who happen to use Commons, but not FOP or Batik, but as part of a special xmlgraphics-commons.jar that is built especially for the two sub-projects. Cheers Andreas
Re: Feedback on Processing Feedback
Hi Vincent On 30.01.2008 12:10:58 Vincent Hennebert wrote: Hi Jeremias, As far as I understand the event-model.xml and test-event-model.xml files are automatically generated at build time. Is there any reason to put them under version control then? Good catch. I guess I was confused by the necessity to place the generated translation files under version control. But the model files don't need to be there. I'll fix that. And this one is more to myself, to be sure I understand how things are working. At several places you do something like this: SAXTransformerFactory tFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); But the SAXTransformerFactory class doesn’t re-define the newInstance method, which then is taken from TransformerFactory. AFAIU, to be sure it will create a SAXTransformerFactory instance you need to play with the javax.xml.transform.TransformerFactory system property. Which IIC is not done anywhere, so it relies on the platform default, which obviously happens to actually create a SAXTransformerFactory. It’s ok, I’d just like to know if I am right in my assumptions? Correct. There's no need to play with a system property for this to work. The only requirement the above imposes on the system is that a TraX implementation with support for the SAXTransformerFactory is available (and after all we need a SAXTransformerFactory in most places because FOP makes extensive use of the passive XML handling pattern, ex. Fop.getDefaultHandler()). Most implementations always just return a SAXTransformerFactory anyway. However, there's one thing in this context that is still on my list and that I want to change eventually: We have multiple places where we create a new TransformerFactory. It's always the platform default that is used. Some FOP users have asked before that there be a default that is set to and applies to FOP only, i.e. we need a central SAXTransformerFactory for FOP. Using a TransformerFactory just to serialize data into an XML file may sound a bit weird (this has nothing to do with XSLT). It appears that Xerces defines an XMLSerializer class dedicated to that. Basically the following: Result res = new StreamResult(outputFile); SAXTransformerFactory tFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); TransformerHandler handler = tFactory.newTransformerHandler(); Transformer transformer = handler.getTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, yes); handler.setResult(res); handler.startDocument(); object.toSAX(handler); handler.endDocument(); would be replaced by the following: ContentHandler handler = new XMLSerializer(new FileWriter(outputFile), new OutputFormat(xml, UTF-8, true)); handler.startDocument(); object.toSAX(handler); handler.endDocument(); Since we have switched to Java 1.4 as a minimum requirement, the xercesImpl dependency is no longer required, but since we have it already, why not keeping it for that. WDYT? It's a possibility but not one I like too much. I know about the XMLSerializer but I didn't use it explicitely to avoid a hard dependency on Xerces and because it's actually deprecated. See: http://svn.apache.org/viewvc/xerces/java/trunk/src/org/apache/xml/serialize/XMLSerializer.java?view=log Xerces's serializer has been merged with the one from Xalan and Xerces now ships that serializer in their latest releases. The new serializer is this one (found in serializer-2.7.0.jar in our lib directory): http://svn.apache.org/viewvc/xalan/java/trunk/src/org/apache/xml/serializer/ (XML serialization is found in ToXMLStream, never used it myself) The main reason why I prefer the Transformer pattern (and I really use it everywhere) is an educational one. If you look at our embedding examples [1] I've used this pattern everywhere. I believe it makes it easier especially for beginners to work exclusively with the Transformer pattern because it's very simple but still extremely flexible. I'm even parsing XML that way if I don't need any special features that I would only get with SAXParser or DocumentBuilder. Basically, you just use the same pattern everywhere and you don't need to know the specifics of SAXParser, DocumentBuilder, XMLSerializer or ToXMLStream and it works with every decent JAXP implementation. [1] http://xmlgraphics.apache.org/fop/0.94/embedding.html BTW, even Xalan suggests to use the Transformer pattern to serialize XML: http://xml.apache.org/xalan-j/usagepatterns.html#serialize Jeremias Maerki
Re: Feedback on Processing Feedback
On Jan 30, 2008, at 13:01, Jeremias Maerki wrote: Hi Jeremias, Vincent, snip / However, there's one thing in this context that is still on my list and that I want to change eventually: We have multiple places where we create a new TransformerFactory. It's always the platform default that is used. Some FOP users have asked before that there be a default that is set to and applies to FOP only, i.e. we need a central SAXTransformerFactory for FOP. I agree with the intention, but not with duplicating the endorsed standards mechanism, as noted in the other thread. The context where this is applicable, is not really simple CLI-usage, so my reasoning would be: If an embedding user needs to instantiate the basic TransformerFactory himself, FOP should probably simply keep a reference to that, and use that single factory internally. For example, a user could decide to force a hard dependency on Saxon: SAXTransformerFactory tFactory = (SAXTransformerFactory) net.sf.saxon.TransformerFactoryImpl.newInstance() If we make it possible for him to pass this factory into the FopFactory or FOUserAgent, and we replace all internal references to TransformerFactory to use this instance, that should provide him with more than enough flexibility. [Vincent:] Using a TransformerFactory just to serialize data into an XML file may sound a bit weird (this has nothing to do with XSLT). It appears that Xerces defines an XMLSerializer class dedicated to that. snip / It's not weird at all, if you look at what is needed to serialize your data into a different format --possibly non-XML. Using the XMLSerializer, you would either: a) need a different sort of Serializer (properietary?) b) if the target is still XML, you /could/ add an XSLT step before the serialization Now, looking at it this way, why not simply use an identity Transformer to begin with. If your output target changes, all you need to do is write a stylesheet (which is much simpler than implementing your own Serializer), and alter one or two lines of Java code (some more if you also want the stylesheet to be pluggable). Cheers Andreas
Re: Feedback on Processing Feedback
I'm not sure, yet, if it's so easily possible to get the TransformerFactory from the FopFactory as it's not available everywhere. This could take some additional wiring. At first I was simply thinking about a classloader-wide setting (i.e. static variable) plus a system property. After all, it's not just FOP that instantiates Transformers, but XML Graphics Commons and Batik, too. I'll look into it. On 31.01.2008 00:11:43 Andreas Delmelle wrote: On Jan 30, 2008, at 13:01, Jeremias Maerki wrote: Hi Jeremias, Vincent, snip / However, there's one thing in this context that is still on my list and that I want to change eventually: We have multiple places where we create a new TransformerFactory. It's always the platform default that is used. Some FOP users have asked before that there be a default that is set to and applies to FOP only, i.e. we need a central SAXTransformerFactory for FOP. I agree with the intention, but not with duplicating the endorsed standards mechanism, as noted in the other thread. The context where this is applicable, is not really simple CLI-usage, so my reasoning would be: If an embedding user needs to instantiate the basic TransformerFactory himself, FOP should probably simply keep a reference to that, and use that single factory internally. For example, a user could decide to force a hard dependency on Saxon: SAXTransformerFactory tFactory = (SAXTransformerFactory) net.sf.saxon.TransformerFactoryImpl.newInstance() If we make it possible for him to pass this factory into the FopFactory or FOUserAgent, and we replace all internal references to TransformerFactory to use this instance, that should provide him with more than enough flexibility. snip/ Jeremias Maerki