Glen Mazza wrote:

> > Well, the public API has to have
> > some way to control
> > the whole show.
> You don't mean that literally--e.g.., a servlet
> programmer does not need useThisRenderer() and
> attachAreaTree() functions in a public API.  (i.e.,
> the public (embedded) API would be a strict subset of
> the functions available to the supervising octopus
> running the show)

I am not sure what Jeremias meant, but yes, the API needs to at least
indirectly control all of the major decisions. In my vision of the API, the
servlet programmer would not need useThisRenderer(), but would need
something like setOutputType(OUTPUT_PDF), which would ultimately cause the
correct renderer to be selected. More likely, it would be set in a
constructor. Here is  some simplified sample startup code:

        session = new Session;
        document = session.addDocument(inputFile);
        document.addRenderType(RENDER_PDF, LAYOUT_SIMPLE, outputFile1);
      document.addRenderType(RENDER_POSTSCRIPT, LAYOUT_SIMPLE, outputFile2);
        document.addRenderType(RENDER_PDF, LAYOUT_CLASSIC, outputFile3);
        session.process()  // if you want session to manage a queue of documents

>From a big-picture control standpoint:
        Document = FOTree
        RenderContext = AreaTree
        RenderType = Renderer

The document.addRenderType() also builds any RenderContext objects that are
needed, three in this example (the first two can share the same AreaTree,
each of the others requires a different one). When document.process() is
run, it looks at the RenderContext objects to determine whether an FO Tree
needs to be built In this case it does (and yes, it should be in a different
package). It can then loop through the RenderContext objects to see what if
any layout work needs to be done, and build an Area Tree based on the output
type and the selected LayoutStrategy. Each RenderContext object will then
loop through the RenderTypes which are attached to it to fire up Renderers.
So in the example above, the same AreaTree will be used to spit out the
first two RenderTypes before trying to build the AreaTree needed for the
"CLASSIC" layout.

Of course, there are a number of configuration options available as well,
all of which can be attached to the appopriate object by a servlet
programmer. The actual using of those options is in other objects (and
indeed, should be in other packages), but the /control/ mechanism can live
in these four classes.

(I have left eager/patient processing out of this example, but control
should be returned to the Document object at the end of each PageSequence to
see if eager processing needs to fire off some layout and rendering work
before continuing with parsing. I am not entirely sure whether eager/patient
processing is totally a function of the LayoutStrategy, or whether some
LayoutStrategies can tolerate either, which would make it need to be

> > This will automatically lead to a
> > little octopus if the
> > code is in ...fop or ...fop.api. But no problem with
> > another package.
> >
> For my discussion, apps=api (they're both supervising
> octopi).  (Although I'm sure your package would be
> orders-of-magnitude cleaner and simpler!)
> > > FOP is more a pipeline to me:
> > >
> > > APPs package (CLI, TRAX/XSLTInputHandler,
> > Avalonized
> > > API, Victor's ideas) -->
> > FOTreeBuilder/Layout/Area
> > > Tree creation --> Rendering.
> >
> > Uh, thanks for that one. It's a very nice show why
> > the current apps
> > package is a mess.
> I agree with you that the apps package is hideous--but
> a pipeline may cleanup nearly all of it, providing it
> enforces the rules I mentioned earlier:
> a.) The only access between apps/api and the rest of
> the packages is via FOTreeBuilder and its "three"
> functions.
> b.) FOP is designed such that FOTreeBuilder *can* be
> directly instantiated via a servlet (even if we don't
> allow it).
> c.) Once so instantiated, no code within apps/api
> packages can be referenced.
> Via these rules, look at what gets removed from apps:
> (a) structure and layout handler are gone (those are
> past the FOTreeBuilder)
> (b) AWTStarter and PrintStarter are gone (those
> processing decisions are either handled by
> FOTreeBuilder or something that it delegates to.)
> (c) App class has *no* knowledge of renderers, element
> mappings, area trees, structure handlers.
> (d) Business logic is kept with each object, and not
> shared in multiple places.
> > > IMO FOTreeBuilder should just expose three
> > functions
> > > (perhaps another one for logging):
> >
> > It's best to talk about
> > lifestyle primarily and
> > leave the lifecycle (instantiation, logging,
> > configuration,
> > initialization) to a different discussion. Helps
> > keeping the focus, I
> > believe.
> Excellent!  We can leave that distraction out of the
> discussion.  (Although they, in addition to threading
> issues, *do* appear to strengthen your argument on the
> need for a supervising class.)
> > > 1.) SetXSLFOStream() (file or stream)
> > > 2.) SetRenderType()  (those constants currently in
> > > Driver or CommandLineStarter)
> > > 3.) Run(). (returns a stream or file)
> >
> > This mixes concerns. A render type does not belong
> > in a class called
> > FOTreeBuilder.
> I think it does, because it needs to know whether or
> not to generate an Area Tree, *which type* of
> structure handler, etc., also, since the Area Tree
> needs to know the render type, FOTreeBuilder will need
> to pass that information on to it via the pipeline.
> (Peter had said and you confirmed that the Area Tree
> still needs to know the rendering type for font sizes,
> etc.)

There is a semantics problem here. I agree with Jeremias' raw point about
the naming of the class. FOTreeBuilder should only build an FOTree under the
direction of some higher-level class (the one I call Document above). And it
wouldn't know about how the FOTree would be used.

> Furthermore a different implementation of
> FOTreeBuilder may make different Area Tree decisions
> based on its render_type.
> > It should have nothing to
> > do with the
> > rendering aspect, especially since FO tree building
> > is independant of
> > the output format (wrt Renderers).
> Indeed, nothing to do with *rendering* but it does
> need to know the render_type as mentioned above.
> APPS/API knows nothing but FOTreeBuilder, which knows
> nothing but AreaTree, which knows nothing but the
> Renderers.
> So I also agree with you that FOTreeBuilder doesn't
> need to know about the Renderers.  (but it could be so
> redesigned in the future, depending on the pluggable
> implementation of FOTreeBuilder, and this design more
> easily allows for that type of change.)
> > The render type
> > is better placed in a
> > class such as a
> > RenderingRun/Document/<whatever-we-call-it>.

[Responding to Jeremias here] Or, better yet IMO, into a RenderType object
that is a child or grandchild of the Document, so that there can be multiple
RenderTypes for the same Document.

> Sure, providing they pass that information on to
> FOTreeBuilder.  ;)
> > The FO
> > tree
> > builder is (to me) a service that simply accepts a
> > SAX stream and builds
> > the FO tree.
> IMHO FOTreeBuilder is an object (C++/Java), not a
> service (C).
> > The layout engine, another (coarse
> > grained) service, will
> > then access the FO tree to do the layout. This is
> > all kept together by a
> > "supervising" class.
> If we were doing C programming--my fear is that the
> supervising class is going to end up eating FOP's
> object-oriented design and splitting the business
> logic too much in multiple places (just like apps
> currently does).  (I guess I'll just have to trust the
> team to be disciplined in this regard!  ;)
> >
> > The FOTreeBuilder should remain an inner service to
> > FOP, not exposed in
> > the public API, if you ask me.
> OK, a *very* thin wrapper (for those not needing any
> of the threading/logging goodies in apps/api):
> public class Fop extends FOTreeBuilder { }
> user's embedded code:
> Fop.setXSLFOStream(blah);
> Fop.setRenderType(RENDER_PS);
> myDoc = Fop.Run();

In the model I am proposing, threading can be used or not, at whatever
granularity is desired.  I think it would even be possible (I haven't
thought all the way through this), for Session to be passed a maximum number
of threads to control. If that number is two, and there is only one Document
in the queue, it might allow document to run two RendererTypes at a time, or
run two RenderContexts at a time, or whatever. (This idea is not
half-baked -- in truth, the batter is not even stirred, nor the ingredients
purchased. It just seems possible). For those who need simple, you just
create a Session, a Document, a RenderType, and process the Document.

Victor Mote

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

Reply via email to