From: "Joerg Pietschmann" <[EMAIL PROTECTED]> > Jeremias Maerki <[EMAIL PROTECTED]> wrote: > > By the way: What's the current agreement whether to use Avalon or not? I > > mean, we're already using LogKit (which is cool). > > No, it's not cool unless done properly. I don't think users > who want only pure FO processing should be forced to use > another heavyweigth framework and logkit.
I've used Avalon framework in many projects, and IMHO it's not heavyweight. Logkit is *very* light and fast, and I would humbly suggest to take a look at the framework/logging classes that shields logging from implementation. In this way any logger can be plugged in without changing code. > I rather imagine something like the following layered > architecture: > > 1. FOP core. Processes XML, either as SAX event stream by > supplying a content handler or by utilising the interface > javax.xml.transform.Source, into a renderer specific result > (probably a java.io.OutputStream, could even apply to a voice > renderer :-) > Do not rely on any hardcoded external files. Get configuration > via a java.util.Properties object or other explicit methods. In my experience, using the avalon framework Configuration adds a *lot* of flexibility and is very easy to use. Now it also has writing capability. Using XML, it has a hierarchy. > Use a FOP owned interface like javax.transform.ErrorListener for > reporting errors and such, or perhaps even reuse ErrorListener > (somewhat odd, though). In error reporting there are wo levels: user and developer. The user gets notified by ErrorListener, the developer by logging. The user could also want to put a logger as errorListener. Anyway avalon frameworl logging shields from the logging implementation. > Use a javax.transform.URIResolver or a similar FOP owned > interface for resolving URIs (external graphics source, user > font file...). There is already a tried and tested Avalon Component for this. > 2. Intermediate layer with a class combining a transformer and > a FO processor instance (optional) > 3. Class for embedding into the framework. Provides implementations > for the URIResolver and the ErrorListener, the latter redirecting > to the logging toolkit. May read external, user writable configuration > files. Uses framework for passing options and other parametrisations > from the outside (command line, servlet request, applet parameter...) There is already a CLI util class in Avalon. > It may be an idea to use the factory pattern like javax.transform: > > abstract classe FOProcessorFactory { > // get a new factory. factory may cache default properties for > // processors, fonts,... > static FOProcessorFactory newInstance(); > // create a new processor. a FOProcessor instance is only good > // for one run, like a Transformer > abstract FOProcessor newFOProcessor(); > abstract FOProcessor newFOProcessor(<Renderer enumeration>); There are ComponentManagers in Avalon, that handle lifecycle automatically. > // inherited to generated processors > abstract void setErrorListener(ErrorListener); > // inherited to generated processors. use also for example for > // loading default fonts while creating a new processor instance > abstract void setURIResolver(URIResolver); > // set attributes, like font file URIs or even compiled font > // classes > abstract void setAttribute(String name, Object value) > // perhaps a few shortcuts for transformations > abstract void setTransformation(Source xsl); > abstract void setTransformation(Templates); > // various get methods omitted :-) > } > > abstract class FOProcessor { > abstract void setRenderer(<Renderer enumeration>); > abstract void render(Source,OutputStream); > > abstract void setErrorListener(ErrorListener); > abstract void setURIResolver(URIResolver); > abstract void setAttribute(String name, Object value) > // shortcuts > abstract void setTransformation(Source xsl); > abstract void setTransformation(Templates); > // extra shortcut (makes no sense for the factory) > abstract void setTransformation(Transformer); > } This is basically a definition of an interface of a FOProcessor, the main avalon-style Component for FOP. Using Excalibur ComponentManager, you just need to add a reference in the xml configuration and it gets automatically setup, configured, and managed. > If a transformation is set, the Source in render() is the original > XML piped through the transformation. I'm not sure whether get/set/ > clearParameter for the transformation should be added to FOProcessor, > fortunately, no output properties are necessary. If it implements the Parametrizable interface of Avalon, the Parameters get set automatically by Excalibur. Same with Configurable. IMHO, Avalon *really* helps in making a clean class structure and Componentization. I am finding it a bit difficult in getting the grasp of FOP specific stuff, but understand something of Avalon, so I'm very willing to help in this regard. Cheers! Ken -- Nicola Ken Barozzi krysalis.org - verba volant, scripta manent - (discussions get forgotten, just code remains) --------------------------------------------------------------------- --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, email: [EMAIL PROTECTED]