--- Jeremias Maerki <[EMAIL PROTECTED]> 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. [1] http://marc.theaimsgroup.com/?l=fop-dev&m=109261374110951&w=2 > 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. Thanks, Glen