[Tibor Vyletel]

Hello Fopsters,

I use FOP (dev 1.0) in a bit different scenario as you. My renderer works in
GEF framework. Till now, I have hacked simple change in relevant layout

BlockLayoutManager.getParentArea(Area childArea) {
    // this creates connection between fobj and curBlockArea:
    curBlockArea.addTrait(Trait.ID_AREA, this.fobj);

This solution is just a hack and a maintainance nightmare, as the design is
constantly changing ;)
I am aware that described construction is breaking memory optimization
goals, however I need it to achieve my goal: enable editing after the
rendering process and make this editing as responsive as possible.

Lately (in fact, after the removal of getID() method from FObj), I've been
thinking about more elegant solution which would allow me to track a mapping
between FObjs and Areas in cases I need it. I know that any technique which
would force this connection in standard processing would not be possible,
because its effects on memory consumption would be relevant.

My alternative idea is:
- create AreaFactory interface (or abstract class) which would be
responsible for creation of areas. Provide default implementating class with
today's functionality scattered among LMs.
    There are to choices how to design this interface:
    a) with one strong method: Area createArea(LayoutManager lm, FObj fobj,
Object constraints)
    b) with a set of specialized methods for creation of different area
        Inline createInline(...) {}
        Block createBlock(...) {}

Would you need to return subclasses of Inline and Block etc? Or would you just set various additional traits such as this.fobj?

- refactor instantiation of area objects in layout managers: remove all
direct instantiations and replace them with calls to DefaultAreaFactory
- solve how to configure AreaFactory before layouting process. Layout
managers don't have access to UserAgent so far, so the best method would
probably be a pair of static methods:

Actually, LMs normally has access to the fobj and through that the FONode.getUserAgent() method.

    AreaFactory AreaFactory.getFactory()
    AreaFactory.setFactory(AreaFactory factory)
    and this constructrion in LMs:
    currArea = AreaFactory().getFactory().create....

When this pattern would be applied, my problem would be simply solved by
creation of descendants for some Area classes, which would hold reference to
the FObj data. Default implementation would bring no extra memory
consumption and/or relevant speed degradation.

The reason why I have written this mail, is to obtain some feedback about
suggested refactoring. In fact I am forced to do some changes to the FOP
code because of my project's special requirements.

Would you still need to change FOP sources, even after your proposal was implemented?

The real payback for me
would the case when all the maintainance nightmares would be gone and this
can happen only when creation of Areas is more modular. I think that
modularization of this could bring its two cents to the quality of the FOP's
source code.

From your description I sort of get the impression that a smaller change, such having all LMs call a new method, say


which has a default empty implementation. Would it be good enough for you to change AbstractLayoutManager to add your special requirements?


Reply via email to