Using Avalon/Logkit Was: Re: [Understanding] Images [4]

2002-02-26 Thread Joerg Pietschmann

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 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.
 Use a FOP owned interface like javax.transform.ErrorListener for
 reporting errors and such, or perhaps even reuse ErrorListener
 (somewhat odd, though).
 Use a javax.transform.URIResolver or a similar FOP owned
 interface for resolving URIs (external graphics source, user
 font file...).
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...)

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);
  // 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);
}

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.
There could be all kind of embeddings or standalone applications
provided based on this interfaces. AWT rendering may need some more
thought, i have no experience how this works. I'm uneasy about
creating renderer objects separately, but it may be necessary.

Regards
J.Pietschmann

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]




Re: Using Avalon/Logkit Was: Re: [Understanding] Images [4]

2002-02-26 Thread Nicola Ken Barozzi

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