You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-dev@xmlgraphics.apache.org by Joerg Pietschmann <jo...@zkb.ch> on 2002/02/26 18:01:33 UTC

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

Jeremias Maerki <je...@outline.ch> 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: fop-dev-unsubscribe@xml.apache.org
For additional commands, email: fop-dev-help@xml.apache.org


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

Posted by Nicola Ken Barozzi <ba...@nicolaken.com>.
From: "Joerg Pietschmann" <jo...@zkb.ch>

> Jeremias Maerki <je...@outline.ch> 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: fop-dev-unsubscribe@xml.apache.org
For additional commands, email: fop-dev-help@xml.apache.org