xmlgraphics-fop-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Glen Mazza <grm7...@yahoo.com>
Subject Re: cvs commit: xml-fop/src/java/org/apache/fop/apps FOUserAgent.java
Date Mon, 11 Oct 2004 23:20:54 GMT
--- Jeremias Maerki <dev.jeremias@greenmail.ch> wrote:

> Glen,
> I don't
> particularly like selecting renderers by integer
> constant. 

FOP has been using integers for six years now, and as
I explained earlier [1], MIME types don't make a very
good primary key for renderers, because not all
renderers have a MIME type, also multiple renderers
can share the same MIME type (e.g. our PDF renderer
and Finn's version of it.).  In some cases, we would
may indeed need a RENDER_PDF_V14 and an
RENDER_PDF_V15, for example. 

Again, integer constants also work well in arrays,
they are ultra-fast, and, as a bonus, "new
Fop(RENDER_PFD)" is a ultra-quick-to-catch
compile-time error, while new FOP("application/pfd")
would turn into a pesky run-time error (and even a ML
question).  The integer constants are also much easier
to remember than MIME types:  RENDER_ followed by the
desired render type. 


> I like
> pluggability. 

We sufficiently have that for our next release, where
I define "sufficiently" as "as much as we have already
in 0.20.5, and basically what AH/RX offers".  We have
already learned that adding too many hooks,
interfaces, visitor patterns, *before* the
layout/renderer work is done, results in FOP never
getting finished because the code becomes too hard to
work through.  So let's get the code working first
(moving the renderers over, whitespace handling, PDF
bookmarks, layout), *then* put it into Mandarin with
the advanced API many desire.  

I share your impatience with the next release not
coming out yet, but we have to keep the code simple to
get more people to look at and help in the code.

> I'd prefer to register all our
> renderers in a central
> registry. Integrators could plug in their renderers
> using the service
> interface just as the FOP extension can. 

That's beautiful post-0.30/1.0 talk that should be
added to our roadmap.  But, in the meantime, we
already have a perfectly satisfactory
FOUserAgent.setRendererOverride() that will satisfy
the users that currently have renderer overrides.  I
would prefer a minimal API with as much black-boxed as
possible to allow future implementors as much
architectural freedom as possible.

Besides, what you prefer now is not what the team
preferred six months ago, or a year ago, or 18 months
ago, etc., etc.  Our API/internal architecture desires
keep changing. 

> You could
> even override
> renderers (for "application/postscript" for example)

We already have that with
setRendererOverride(Renderer).  You can't use MIME
type for reasons given above.

> if you have a
> renderer with some custom extensions. IMO
> FOUserAgent is already
> overloaded with too many different things. 

That is because we tend to, whenever any user might
want something, give him/her an API method for it. 
The only way we can satisfy these many needs without
forever locking the FOP architecture (each of these
switches internally modifying the behavior of one
internal class or another) is to add the method to
FOUserAgent, and have internal classes read it, rather
than the other way around.  Furthermore, we have one
class--FOUserAgent--for these parameters to make the
embedded/servlet API easier for non-advanced users. 
(BTW, FOUserAgent should be reduced somewhat anyway,
when we create fox:metadata or whatever.)

> I think
> that the overrides
> don't belong there, or rather they are probably
> unnecessary given a
> better renderer selection mechanism.

Oh, I think they do, it is sufficient for our next
release.  Nothing is easier, nothing is simpler for
embedded/servlet users.  Take a look at the 1.0
embedded examples.

> What triggered the creation of the RendererFactory
> was not IoC but the
> other Avalon concept: Separation of concerns. I
> think that handling
> renderer and FOEventHandler creation in a separate
> class rather than in
> the quite crowded FOTreeBuilder and RenderPagesModel
> improves code
> readability.

FOTreeBuilder and RenderPagesModel IMO aren't that
crowded, they are the size they need to be for the
business logic they are responsible for.  Still, I've
bent over backwards to remove as many classes and
unneeded methods to simplify the code as much as
possible.  Furthermore, bouncing around classes IMO
raises stress rather than lowering it.  

As for Avalon SoC, the concerns *were* properly
separated:  the FOTreeBuilder chose the FOEventHandler
based on the desired render type, and RenderPagesModel
chooses its renderer also on the desired render type. 
It is business logic purely the departments of the
FOTreeBuilder and RenderPagesModel.

Still, I'm not objecting to this change as long as
it's not the external API.  (Indeed, I support it,
because it makes you happy, and when you're happy
you're more productive.)

> Don't get me wrong. I can live with the current
> situation as long as I
> can plug in my custom FOEventHandler. You don't
> object to that, do you?

Not at all, because it does not directly touch
internal code.  Future committers can move
FOEventHandler handling anywhere they like without the
FOUserAgent method changing. 

> By the way, my change didn't change the end-user
> API, so I don't see any
> reason why RendererFactory is a bad idea. Do I miss
> your point?

Only if you were planning on exposing RendererFactory
to the external API.  It is the fact that the end-user
API didn't need to change for your internal change, is
why my design of FOUserAgent is solid.  (Think of a
database view--where the view accesses several
underlying tables.  By having applications query the
view instead of the tables, the DBA/Data Modeler is
able to make table changes without concern about the
application needing updating--only the view definition
changes.  This is what I would like our API to be.)

Future committers must have the ability to get rid of
RendererFactory for something they deem better, just
like you changed my design for something you thought
was better.  Our external API should mask our internal
workings--which, along with keeping things simple, are
my main concerns here.  

Sorry for the long (and perhaps repetitive) post.


View raw message