On 08.02.2006 22:03:30 Simon Pepping wrote:
> Jeremias,
> 
> On Tue, Feb 07, 2006 at 10:09:38AM +0100, Jeremias Maerki wrote:
> > As part of my upcoming optimization work I want to finalize the FOP API.
> > I've written down a proposal in the Wiki:
> > http://wiki.apache.org/xmlgraphics-fop/ApiDesign
> > 
> > If possible, I'd like to have that finished by the end of the week.
> > Please post your feedback ASAP.
> 
> Some remarks and questions.
> 
> 1. D11, D12: FopEnvironment should be FopFactory?

Yes, of course. I had FopEnvironment at first and then decided to more
closely follow the JAXP pattern.

> 2. How does FOUserAgent differ from FopFactory? What is rendering run
>    dependent in FOUserAgent, now and in the future?

FOUserAgent is the object which acts as an agent for the user in a
transaction (i.e. rendering run). It's the central interaction point in
both directions. The user gives settings for the document currently
being created. FOP, on the other side, can communicate with the user
through the user agent by telling him about layout problems, for example
(user feedback mechanism I want to propose later).

FopFactory on the other side is the place where things are configured
that will be used for multiple rendering runs. Take font configuration,
for example. That won't likely change between rendering runs. You set it
up once and you also want FOP to initialize the font setup only once and
reuse it for every rendering run for performance reason. Font
initialization is a rather expensive operation. Similarly, the image
cache will also be attached to the FopFactory.

Rendering run dependent is stuff that is specific to a single document
and may potentially be different for the next document, i.e. metadata,
specially set up renderers, PDF encryption parameters etc. Granted,
there is no hard line here. It may well up subject for discussion what
ends up where. I tried to do a good division.

> 3. Is FopFactory's main role being a factory, or being a configuration
>    holding object across rendering runs? I am not charmed by the name
>    FopFactory; it does not seem to describe its role, only a side
>    effect of its role, viz. spawning rendering runs.

I agree with you that FopFactory may not be ideal. If there's a better
choice, I'm open to suggestions. I've tried to model everything as close
as possible to the JAXP Transformer API because that's what people
already know. And even the TransformerFactory has a double-function:
It's a factory in the pattern sense and it holds configuration values
that will affect the instances created through the factory methods.

> 4. You write about XML configuration. Can the configuration on a fop
>    factory also be set using an Avalon Configuration object?

ATM, configuration is exclusively set using an Avalon Configuration
object. That will remain but I'd like to add one or two additional
methods where people can simply specify an URL or a java.io.File and FOP
does the config file loading.

> 5. Do I understand correctly that the main alternatives to start a
>    rendering run are:
> 
>    A.
>    Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF);
> 
>    B.
>    FOUserAgent userAgent = fopFactory.newFOUserAgent();
>    userAgent.setTitle("My document");
>    Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, userAgent);
> 
>    The difference being that in method B one can set properties that
>    are specific to this rendering run?

That kind of pattern is already used today. Only the way the user agent
and the Fop instance are instantiated is different. People who are happy
to convert using the default settings can omit specifying the user agent.
Fop uses a default user agent in this case. No change to the current
behaviour at all.

> 6. D5 (The FOUserAgent can return the FopFactory instance. (needed
>    internally by FOP)): Why? Because FOUserAgent is the programmed way
>    to get at configuration settings? Could it be better to implement
>    get methods on the user agent which get the settings from the
>    factory object (factory object not exposed)? Or even pass the
>    factory object instead of the user agent (Cf. question 2)?

We're already passing down the FOUserAgent in a number of places and
it's a good place to access central resources. If it is preferred I have
no objections to access the FopFactory values directly through method on
the FOUserAgent although I expect additions to the FOUserAgent in the
future and separating certain things to the FopFactory will clean it up
a little and make it clear on what level the values/services are
available. And yes, we could pass down the factory instance instead of
the user agent. That is certainly a possibility, one that may make sense
in certain places. Again, I'm open to suggestions. I haven't fully made
up my mind and I've asked for feedback to get additional eye-pairs on
the proposal.

> 7. What is the difference between these to instantiation methods:
> 
>    FOUserAgent userAgent = fopFactory.newFOUserAgent(); (D6)
>    FOUserAgent userAgent = new FOUserAgent(fopFactory); (D3)

D3 is intended for use by the FopFactory. The user is not really
supposed to call the constructor directly. With the current proposal
there's no harm if someone uses the FOUserAgent constructor directly,
but we could of course hide it by making the FOUserAgent into an
interface. But I don't think it's really necessary. It's probably a
similar argument as Jesse Holle's on the Fop constructor.

Thanks for the feedback!!!!

Jeremias Maerki

Reply via email to