You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-dev@xmlgraphics.apache.org by Finn Bock <bc...@worldonline.dk> on 2004/08/27 21:31:43 UTC

validateChildNode prevents extensions.

Glen

I think that the new validateChildNode() methods are too strict in 
response to extension elements. My guess is that the validation should 
only occur when one fo namespace element is added to another fo element.

For instance, Block.validateChildNode() doesn't allow any of my 
extension elements as children.

regards,
finn


Re: validateChildNode prevents extensions.

Posted by Clay Leeds <cl...@medata.com>.
On Aug 29, 2004, at 1:15 PM, Jeremias Maerki wrote:
> On 29.08.2004 20:57:54 Simon Pepping wrote:
>> On Sun, Aug 29, 2004 at 08:15:38PM +0200, J.Pietschmann wrote:
>>> Glen Mazza wrote:
>>>> You have a new FO, you're going to need to code for
>>>> them--including ordering and cardinality--in those
>>>> parents that accept them,
>>>
>>> This does *not* necessarily mean that *you* should arrange
>>> that the extension writer has to replace core FO classes.
>>> In fact do either:
>>> 1. Declare FOP wont support extensions except in
>>>  instream-foreign-object, ever, or
>>> 2. Provide hooks so that extension writers can get their
>>>  extensions running with FOP, with or without extensive
>>>  validation of the extended content model, but at least
>>>  *without* having to rewrite and replace core FO classes.
>>
>> My thoughts are along the same lines that Jörg has argued. I think we
>> should do option 2. vCN() should be written such that it allows this.
>
> While I choose not to participate in FO-tree and layout engine design
> but having written a number of FOP extensions, I agree with this view,
> too.

I tend to prefer option 2: an extension writer should not have to 
modify the FOP source in order to get the extension to work. (In fact, 
when I think of extensions, I think of them like "PLUGINS" to 
Photoshop... not only do they work, but--in a perfect world--it would 
be nice if they could also work with other programs that support "Adobe 
Photoshop PLUGINS" as well--e.g., RenderX, Antenna House, etc.).

As for any 'extensions' built-in to FOP--namely fox:--I believe they/it 
should be removed from FOP, and turned into a 'real' extension whilst 
retaining their/its current functionality. This 'new' extension should 
then be distributed with the FOP binary and source in a 
PLUGINS^H^H^H^H^H^H^H extensions/ sub-directory.

> It must be stated, though, that 99 out of 100 users
> will not be writing extensions.  Their needs, a solid
> FOP out relatively soon, must not be ignored.
>
> Glen Mazza

Glen's right on the money, that 99 out of 100 users will not be writing 
extensions. However, that 1/100 user might be an IBM developer, writing 
the killer app used by all of the IBM folks (and/or become part of an 
OEM distribution).

Clay Leeds - cleeds@medata.com
-- 
Web Developer - Medata, Inc. - <http://www.medata.com/>
PGP Public Key: <https://mail.medata.com/pgp/cleeds.asc>

Re: validateChildNode prevents extensions.

Posted by Glen Mazza <gr...@yahoo.com>.
--- Jeremias Maerki <de...@greenmail.ch> wrote:
> 
> On 29.08.2004 20:57:54 Simon Pepping wrote:
> > On Sun, Aug 29, 2004 at 08:15:38PM +0200,
> J.Pietschmann wrote:
> > > Glen Mazza wrote:
> > > >You have a new FO, you're going to need to code
> for
> > > >them--including ordering and cardinality--in
> those
> > > >parents that accept them,
> > > 
> > > This does *not* necessarily mean that *you*
> should arrange
> > > that the extension writer has to replace core FO
> classes.
> > > In fact do either:
> > > 1. Declare FOP wont support extensions except in
> > >  instream-foreign-object, ever, or

No, we just summarize the steps needed to modify FOP
by changing its source, or, as Finn prefers, attaching
another library.  Fortunately or unfortunately,
though, an FO Processor has a grammar one has to
follow.  Adding an FO-based element requires the
grammar to change--indeed, you have a brand-new FO
processor when you bring in a new element.  Thankfully
we appear to be all in agreement on this--it is just a
question of implementation.

I still feel the overall complexity involved with
subclassing the Parent FO in Finn's JAR remains much
less than moving from parent-based to child-based
validation.  Further ameliorating this is that many
times you may want to override the parent anyway--for
more hooks or other changes, etc.  But Finn is working
on other solutions for us right now--let's see what he
can come up with.

It must be stated, though, that 99 out of 100 users
will not be writing extensions.  Their needs, a solid
FOP out relatively soon, must not be ignored.  

Glen Mazza


Re: validateChildNode prevents extensions.

Posted by Jeremias Maerki <de...@greenmail.ch>.
On 29.08.2004 20:57:54 Simon Pepping wrote:
> On Sun, Aug 29, 2004 at 08:15:38PM +0200, J.Pietschmann wrote:
> > Glen Mazza wrote:
> > >You have a new FO, you're going to need to code for
> > >them--including ordering and cardinality--in those
> > >parents that accept them,
> > 
> > This does *not* necessarily mean that *you* should arrange
> > that the extension writer has to replace core FO classes.
> > In fact do either:
> > 1. Declare FOP wont support extensions except in
> >  instream-foreign-object, ever, or
> > 2. Provide hooks so that extension writers can get their
> >  extensions running with FOP, with or without extensive
> >  validation of the extended content model, but at least
> >  *without* having to rewrite and replace core FO classes.
> 
> My thoughts are along the same lines that Jörg has argued. I think we
> should do option 2. vCN() should be written such that it allows this.

While I choose not to participate in FO-tree and layout engine design
but having written a number of FOP extensions, I agree with this view,
too.

Jeremias Maerki


Re: validateChildNode prevents extensions.

Posted by Simon Pepping <sp...@leverkruid.nl>.
On Sun, Aug 29, 2004 at 08:15:38PM +0200, J.Pietschmann wrote:
> Glen Mazza wrote:
> >You have a new FO, you're going to need to code for
> >them--including ordering and cardinality--in those
> >parents that accept them,
> 
> This does *not* necessarily mean that *you* should arrange
> that the extension writer has to replace core FO classes.
> In fact do either:
> 1. Declare FOP wont support extensions except in
>  instream-foreign-object, ever, or
> 2. Provide hooks so that extension writers can get their
>  extensions running with FOP, with or without extensive
>  validation of the extended content model, but at least
>  *without* having to rewrite and replace core FO classes.

My thoughts are along the same lines that Jörg has argued. I think we
should do option 2. vCN() should be written such that it allows this.

Regards, Simon

-- 
Simon Pepping
home page: http://www.leverkruid.nl


Re: validateChildNode prevents extensions.

Posted by "J.Pietschmann" <j3...@yahoo.de>.
Glen Mazza wrote:
>>There shouldn't be extensions hardcoded
> I thought of that (i.e., just make us a nice reference
> implementation of the XSL standard), but PDF bookmarks
> are just too popular
[snip]
I didn't meant the bookmark extension should be discarded,
I meant the code should be pulled out of the core into a
separate, loadable extension, using the same mechanisms as
other extensions.

> The content model *of that extension element*,

Wrong, the extension writer also decides in which FO
elements his extension elements can appear. *You*
certainly can't do this now.

> And what about its relative ordering within the
> fo:block?  Or its cardinality?  These are also defined
> in the content model.

The Java object corresponding to the extension element
should have access to the part of the FO tree which
had been already constructed, including preceding
siblings. Constraints involving elements from the FO
namespace like "must precede any fo:* elements" are
a bit difficult, but there are ways around this (registered
callbacks, for example).

> The proper model is the Rec,

This means you want to disallow *all* extensions except
as child of instream-foreign-object. This is a somewhat
strange contradiction to your stance with respect to
the bookmark extension.

> You have a new FO, you're going to need to code for
> them--including ordering and cardinality--in those
> parents that accept them,

This does *not* necessarily mean that *you* should arrange
that the extension writer has to replace core FO classes.
In fact do either:
1. Declare FOP wont support extensions except in
  instream-foreign-object, ever, or
2. Provide hooks so that extension writers can get their
  extensions running with FOP, with or without extensive
  validation of the extended content model, but at least
  *without* having to rewrite and replace core FO classes.
The crude middle way to allow extensions but make it extra
hard for developers to get them working, *and* make it
nearly impossible for independently developed extensions
to cooperate (as Finn already explained to you several
times), is, well, crude, hard, and unnecessary.

> Returning to the old method is not really an option. 
> That's what was causing CCE and NPE's throughout the
> system, whenever the FO was invalidly ordered.

*sigh* I should have time to do it myself. I don't see
why content model checking and drop-in extensions have
to be mutually exclusive.

> If the current node is an fo:list-item and the
> incoming node represents an fo:layout-master-set,
> raise the exception immediately before you even get to
> instantiate the fo:layout-master-set.

This does not mean you have to summarily reject a
finnbock:change-bar on the same grounds.

J.Pietschmann

Re: validateChildNode prevents extensions.

Posted by Glen Mazza <gr...@yahoo.com>.
--- "J.Pietschmann" <j3...@yahoo.de> wrote:

> Glen Mazza wrote:
> > Provided the extension namespace isn't already
> > hardcoded into FOP (like the fox: one).
> 
> There shouldn't be extensions hardcoded into the FOP
> core,
> at least in the long term.
> 

I thought of that (i.e., just make us a nice reference
implementation of the XSL standard), but PDF bookmarks
are just too popular -- as Simon noted, Docbook uses 
ours and RenderX's -- and the commercial
implementations regularly use extensions.  Certain
extensions that are relevant for only a particular
render-type are difficult to get into the
output-neutral XSL recommendation, so we may end up
having several anyway.

Also, as I understand it, extensions in RenderX and
AntennaHouse were the source for new official FO's in
the 1.1 spec (change bars, for example), so I don't
want FOP itself to lose that ability to be the source
of future FO's.  


> > Errr, elements can't "validate themselves",
> because
> > the validity of an element is defined only by the
> > parent.
> 
> The extension writer decides the content model, and
> if

The content model *of that extension element*, i.e.,
the children of that extension element.  Not those of
the parents above it.  The content model for each FO
is defined within that FO.  We're basically building a
syntax-checking compiler, and it has to act as such.  

> an extension element is supposed to be child of a
> fo:block
> only, the corresponding Java object has to get its
> parent
> and verify its actually a fo:block.
> 

And what about its relative ordering within the
fo:block?  Or its cardinality?  These are also defined
in the content model.

Strictly speaking, an extension element cannot be the
child of an fo:block--the children of an fo:block are
defined by the rec, and they are all FO's.  You mean
the child of a particular processor's implementation
of fo:block, one whose content model has been modified
to accept certain extension elements.  OK, but if
that's the case, well, that fo:block's vCN() has
already determined the extension element to be valid.

As I said, the only difference between an formatting
object and and extension element is that the latter
hasn't yet been blessed by the W3C.  Their processing
and validation is the same.  Change bars = 1.0
extension element (RenderX/AH), but a 1.1 formatting
object.

Content models define the valid children of an
formatting object, extension or otherwise.  

> >  The recommendation declares, via the content
> > models, which children are valid for each parent,
> not
> > vice-versa.
> 
> True for elements from the FO namespace *only*.
> 

No, because DTD content models are always defined for
the higher-level (i.e., parent) node.  And it's
strange to suggest that a "candidate FO" can/should be
able to located anywhere, given that all the actual 56
FO's have precise ordering.   


> >  This logic is naturally (and much more
> > cleanly) stored with the parent in the OO world,
> > allowing Finn's block.java to have different child
> > nodes from FOP's block.java.
> 
> There is no "Finn's block.java" in the proper model
> of
> doing extensions. 

The proper model is the Rec, and time and again,
indeed for all the FO's, the content model is defined
for the parents, not for the children.  FinnBlock.java
also has to define the LayoutManager that will handle
it, and in certain cases, the FO's below it--how it
will work with them.  This is simply not dynamically
additive.

You have a new FO, you're going to need to code for
them--including ordering and cardinality--in those
parents that accept them, and subsequently the Layout
which has to handle them.

> 
>  From the viewpoint of a FO element, any elements
> (and
> attributes) from other namespaces are valid and will
> be
> instantiated. 

Returning to the old method is not really an option. 
That's what was causing CCE and NPE's throughout the
system, whenever the FO was invalidly ordered.  The
subsequent error checking in all the methods was
clogging business logic throughout; furthermore
instantiation would otherwise raise other errors, as,
say, fo:layout-master-set tries to read from its
fo:root parent but is instead ends up reading from an
fo:list-item.

If the current node is an fo:list-item and the
incoming node represents an fo:layout-master-set,
raise the exception immediately before you even get to
instantiate the fo:layout-master-set.  Nothing is more
solid and foolproof than that.

Glen


Re: validateChildNode prevents extensions.

Posted by "J.Pietschmann" <j3...@yahoo.de>.
Glen Mazza wrote:
> Provided the extension namespace isn't already
> hardcoded into FOP (like the fox: one).

There shouldn't be extensions hardcoded into the FOP core,
at least in the long term.

> Errr, elements can't "validate themselves", because
> the validity of an element is defined only by the
> parent.

The extension writer decides the content model, and if
an extension element is supposed to be child of a fo:block
only, the corresponding Java object has to get its parent
and verify its actually a fo:block.

>  The recommendation declares, via the content
> models, which children are valid for each parent, not
> vice-versa.

True for elements from the FO namespace *only*.

>  This logic is naturally (and much more
> cleanly) stored with the parent in the OO world,
> allowing Finn's block.java to have different child
> nodes from FOP's block.java.

There is no "Finn's block.java" in the proper model of
doing extensions. An extension writer should only write
the extension. The FOP core must
1. Provide a discovery mechanism for the extension. The
  service file used for this purpose in the maintenance
  branch can be easily extended just by dropping the extension
  jar into the classpath.
2. A configuration mechanism for the extension both for default
  and user supplied values. We don't have this currently.
3. A hook for the extension element factory. Works nicely.
4. A hook for validating the extended content model.
5. Hooks for doing layout and rendering.
Especially the API for the last will take some iterations,
but this doesn't mean

> Furthermore, such a child-level validation would
> require the kid to be instantiated first.  vCN() stops
> instantiation of the kid from ever occurring if it
> would be invalid to begin with.

 From the viewpoint of a FO element, any elements (and
attributes) from other namespaces are valid and will be
instantiated. Then the foreign children get a chance to
validate themselves.
Granted, visible foreign content should be exclusively used
through instream-foreign-object, but this breaks down for
extensions like Karen's extension elements shown before or
after page breaks.

J.Pietschmann

Re: validateChildNode prevents extensions.

Posted by Glen Mazza <gr...@yahoo.com>.
--- "J.Pietschmann" <j3...@yahoo.de> wrote:

> Finn Bock wrote:
> > An extension mechanism where I can put an
> unmodified fop.jar and 
> > myextension.jar on the CLASSPATH and have it work
> is a defining issue to 
> > me.
> 
> That's how it should work. The code build into the
> FOP core
> should only validate elements from the fo namespace
> and
> attributes from no namespace, 

Provided the extension namespace isn't already
hardcoded into FOP (like the fox: one).

> and call validation
> for elements
> and attributes from other namespaces in roder to
> give them a
> chance to validate themselves.
> 

Errr, elements can't "validate themselves", because
the validity of an element is defined only by the
parent.  The recommendation declares, via the content
models, which children are valid for each parent, not
vice-versa.  This logic is naturally (and much more
cleanly) stored with the parent in the OO world,
allowing Finn's block.java to have different child
nodes from FOP's block.java.

Furthermore, such a child-level validation would
require the kid to be instantiated first.  vCN() stops
instantiation of the kid from ever occurring if it
would be invalid to begin with.

Glen


Re: validateChildNode prevents extensions.

Posted by "J.Pietschmann" <j3...@yahoo.de>.
Finn Bock wrote:
> An extension mechanism where I can put an unmodified fop.jar and 
> myextension.jar on the CLASSPATH and have it work is a defining issue to 
> me.

That's how it should work. The code build into the FOP core
should only validate elements from the fo namespace and
attributes from no namespace, and call validation for elements
and attributes from other namespaces in roder to give them a
chance to validate themselves.

J.Pietschmann

Re: validateChildNode prevents extensions.

Posted by Glen Mazza <gr...@yahoo.com>.
--- Finn Bock <bc...@worldonline.dk> wrote:
> > Option #1:
> > 
> > 1.) myextension.jar will need a FOElementMapping
> [1]
> > subclass that will reroute fo:Block from
> Block.java to
> > FinnBlock.java.  Have FinnBlock.java override the
> > vCN() for the new validation rules.  
> 
> This would eventually cause a conflict with the
> GlenBlock.java from an 
> extension written by you.
> 

I don't think so, because there is only one XSL
fo:block element, which must have one and only one
content model.  If I want to incorporate extension
elements from multiple extension jars, I'll need to
code so accordingly in my own GlenBlock.java, which
would incorporate, say, extensions from
FinnExtension.java and extensions from
SimonExtension.java, and define the ordering and
cardinality of the them.  Next, I'd have to create a
GlenBlockLayoutManager that will take care of all of
these different children from different extension
elements.

The children of an fo:block object are just not
dynamically additive:  they are precisely ordered with
cardinality.  For fo:root, for example, the order must
be fo:layout-master-set, fo:declarations?,
fo:page-sequence+, *in that order*.  Content models,
derived from DTD models, do not allow for random
ordering of child elements.

Note this stuff needs to be rendered in layout
eventually anyway, so even if you can dynamically
discover the children of an FO -- and come up with an
algorithm to order them -- you will need to create a
LayoutManager would need to be able to dynamically
handle them as well--eventually these extensions
elements would be conflicting with each other
otherwise.

Glen


Re: validateChildNode prevents extensions.

Posted by Glen Mazza <gr...@yahoo.com>.
I see.  Thanks for the explanation.

Glen

--- Finn Bock <bc...@worldonline.dk> wrote:

> > BTW, without divulging too much that may hurt your
> > interests, would you mind explaining your
> reluctance
> > to just modify FOP source (replace classes, etc.) 
> > for what you are trying to market?  Is it
> licensing
> > issues--or is it more for programmatic style/user
> > convenience?  I want to better understand your
> > reluctance on this matter.
> 
> Legally the seperation between FOP and extension
> have placed a solid 
> wall between my opensource fop-dev work and my
> commercial extension. My 
> client cant claim ownership of any of the fop-dev
> work since the 
> extension didn't require *any* changes to fop.
> 
> Commercially, trying to sell an fork of FOP in order
> to sell an 
> extension to FOP will never fly.
> 
> regards,
> finn
> 


Re: validateChildNode prevents extensions.

Posted by Finn Bock <bc...@worldonline.dk>.
[Glen]

> Oh, when I meant "alter the system" I also meant
> adding classes, using different classes, etc., i.e.,
> some things need to be done beforehand to accomodate a
> new element.

Come on! That leaves "alter the system" without any meaning. Recompiling 
modified sources into a new fop.jar would IMO mean alter the system.

Here is how extensions should work:

      http://xml.apache.org/fop/dev/extensions.html

and that is effectively what I have done.

> BTW, without divulging too much that may hurt your
> interests, would you mind explaining your reluctance
> to just modify FOP source (replace classes, etc.) 
> for what you are trying to market?  Is it licensing
> issues--or is it more for programmatic style/user
> convenience?  I want to better understand your
> reluctance on this matter.

Legally the seperation between FOP and extension have placed a solid 
wall between my opensource fop-dev work and my commercial extension. My 
client cant claim ownership of any of the fop-dev work since the 
extension didn't require *any* changes to fop.

Commercially, trying to sell an fork of FOP in order to sell an 
extension to FOP will never fly.

regards,
finn

Re: validateChildNode prevents extensions.

Posted by Glen Mazza <gr...@yahoo.com>.
Oh, when I meant "alter the system" I also meant
adding classes, using different classes, etc., i.e.,
some things need to be done beforehand to accomodate a
new element.

BTW, without divulging too much that may hurt your
interests, would you mind explaining your reluctance
to just modify FOP source (replace classes, etc.) for
what you are trying to market?  Is it licensing
issues--or is it more for programmatic style/user
convenience?  I want to better understand your
reluctance on this matter.

Glen

--- Finn Bock <bc...@worldonline.dk> wrote:

> 
> >>[Glen]
> >>
> >>
> >>>From what I understand a program may not change
> >>its
> >>>own source code while it is running so we may not
> >>have
> >>>complete freedom for everything.
> >>
> >>I don't know exactly what you mean. I don't think
> >>that such a thing is 
> >>required to have extensible validation for
> >>extensions.
> 
> [Glen]
> 
> > I agree with you there.  But let me elaborate a
> bit on
> > this point--coming in as a committer, I didn't
> > understand the benefits of dynamically loading
> > extension FO's because you would still need to
> alter
> > the area tree,
> 
> Not for the extension I have written. Additional
> area classes, but no 
> changes or replacing of existing classes.
> 
> > layout, 
> 
> No. Additional layoutmanagers, but no changes to
> existing LMs.
> 
> > renderers, 
> 
> No. I wrote my own PDF renderer that is using iText
> as PDF library. So 
> no changes to existing code, but I did have to
> replace the pdf renderer.
> 



Re: validateChildNode prevents extensions.

Posted by Finn Bock <bc...@worldonline.dk>.
>>[Glen]
>>
>>
>>>>From what I understand a program may not change
>>its
>>>own source code while it is running so we may not
>>have
>>>complete freedom for everything.
>>
>>I don't know exactly what you mean. I don't think
>>that such a thing is 
>>required to have extensible validation for
>>extensions.

[Glen]

> I agree with you there.  But let me elaborate a bit on
> this point--coming in as a committer, I didn't
> understand the benefits of dynamically loading
> extension FO's because you would still need to alter
> the area tree,

Not for the extension I have written. Additional area classes, but no 
changes or replacing of existing classes.

> layout, 

No. Additional layoutmanagers, but no changes to existing LMs.

> renderers, 

No. I wrote my own PDF renderer that is using iText as PDF library. So 
no changes to existing code, but I did have to replace the pdf renderer.

Clearly the renderer doesn't support extension areas, but that is a 
weakness in the design of the renderer.

> etc. in order to
> accomodate the new element.  But that code, once
> loaded, cannot be dynamically changed while running. 
> (I'm not talking here about fo:i-f-o children, which
> just get sent off to a different processor)  
> 
> For example, let's say we remove the fox:bookmarks
> from our code, as well as the code from
> AreaTreeHandler.java (and a few other places) that
> work with it.  

The tree extension code in AreaTreeHandler is generally usefull support 
code. I believe that the addBookmarks() and createBookmarkData() once 
lived in Bookmarks.java. Don't know when or why it was moved into the core.

> Instead, we dynamically load this
> element.  While we can load the element itself, we
> will not be able to dynamically rewrite the code in
> AreaTreeHandler, renderers, layout, etc. to accomodate
> this new element, or arbitrarily any new element we
> discover.  (You've noticed that already, as you've had
> to hardcode FOP beforehand to different renderers,
> etc.)  

Hardcode? I did this (in a slightly older version of head):

     Driver driver = new Driver();
     driver.initialize();
     driver.setRenderer(new ITextRenderer());
     driver.addElementMapping(new MyElementMapping());
     driver.render(...);

How is that hardcoding. That is a simple configuration to my 
requirements of the Driver class (as it was called at the time).

> So dynamic discovery for non fo:i-f-o use will
> not be a complete nirvana for an extension
> writer--even if not validation necessarily, some
> (hardcoded) work beforehand will still be needed.

The 1. rule of holes is to stop digging when we find ourself in one.

The current lack of nirvana is no reason to keep digging us deeper into 
the hole.

Instead we should keep the support for extension in the FO classes and 
slowly work on adding support for extension areas to the renderer framework.

regards,
finn

Re: validateChildNode prevents extensions.

Posted by Glen Mazza <gr...@yahoo.com>.
--- Finn Bock <bc...@worldonline.dk> wrote:
> [Glen]
> 
> > From what I understand a program may not change
> its
> > own source code while it is running so we may not
> have
> > complete freedom for everything.
> 
> I don't know exactly what you mean. I don't think
> that such a thing is 
> required to have extensible validation for
> extensions.
> 

I agree with you there.  But let me elaborate a bit on
this point--coming in as a committer, I didn't
understand the benefits of dynamically loading
extension FO's because you would still need to alter
the area tree, layout, renderers, etc. in order to
accomodate the new element.  But that code, once
loaded, cannot be dynamically changed while running. 
(I'm not talking here about fo:i-f-o children, which
just get sent off to a different processor)  

For example, let's say we remove the fox:bookmarks
from our code, as well as the code from
AreaTreeHandler.java (and a few other places) that
work with it.  Instead, we dynamically load this
element.  While we can load the element itself, we
will not be able to dynamically rewrite the code in
AreaTreeHandler, renderers, layout, etc. to accomodate
this new element, or arbitrarily any new element we
discover.  (You've noticed that already, as you've had
to hardcode FOP beforehand to different renderers,
etc.)  So dynamic discovery for non fo:i-f-o use will
not be a complete nirvana for an extension
writer--even if not validation necessarily, some
(hardcoded) work beforehand will still be needed.

Glen Mazza


Re: validateChildNode prevents extensions.

Posted by Finn Bock <bc...@worldonline.dk>.
>>I don't want to change any FOP code! And if I have
>>to change any FOP 
>>sources to add an extension, then FOP doesn't
>>support extension with the 
>>meaning of extension as I understand it.

[Glen]

> From what I understand a program may not change its
> own source code while it is running so we may not have
> complete freedom for everything.

I don't know exactly what you mean. I don't think that such a thing is 
required to have extensible validation for extensions.

>>An extension mechanism where I can put an unmodified
>>fop.jar and 
>>myextension.jar on the CLASSPATH and have it work is
>>a defining issue to 
>>me.  
> 
> OK, this looks like a nice feature to have, and the
> modifications made to FOP in this regard can be
> helpful to others who have similar work to do.
> 
> Here's what I see:
> 
> Option #1:
> 
> 1.) myextension.jar will need a FOElementMapping [1]
> subclass that will reroute fo:Block from Block.java to
> FinnBlock.java.  Have FinnBlock.java override the
> vCN() for the new validation rules.  

This would eventually cause a conflict with the GlenBlock.java from an 
extension written by you.


My own unfinished thinking goes more along the lines of viewing the 
validation between parent and child node as a lookup into a 
2-dimensional table where each row is the parent and each column is the 
child id. The cell then contains the code snippet to check if the child 
is valid.

            |  fo:root  | fo:layout-master-set | fo:block   |  fo:inline
--------------------------------------------------
fo:root       invalid            valid           invalid       invalid
fo:block      invalid           invalid           valid         valid
...

This way an extension can extend the table by putting its own validation 
code into the intersection between fo:block and my:extension.

The state values that is collected during the vCN should be stored in 
validation context that is associated with the node and passed into the 
validation snippet.

The validation for Block could then be implemented with something like this:

class BlockValidation implements Validation {
     public void validated(Locator loc, FObj parent, int childNode,
                           ValidationContext ctxt) throws Exception
     {
         BlockValidationContext bctxt = (BlockValidationContext) ctxt;
         if (childNode == FO_MARKER) {
              if (bctx.blockOrInlineItemFound ||
                  bctxt.initialPropertySetFound) {
                nodesOutOfOrderError(loc, "fo:marker",
                     "initial-property-set? (#PCDATA|%inline;|%block;)");
             }
         else if (childNode == FO_INITIAL_PROPERTY_SET) {
             if (bctxt.initialPropertySetFound) {
                 tooManyNodesError(loc, "fo:initial-property-set");
             } else if (bctxt.blockOrInlineItemFound) {
                 nodesOutOfOrderError(loc, "fo:initial-property-set",
                     "(#PCDATA|%inline;|%block;)");
             } else {
                 bctxt.initialPropertySetFound = true;
             }
         } else if (isBlockOrInlineItem(childNode)) {
             bctxt.blockOrInlineItemFound = true;
         } else {
             invalidChildError(loc, nsURI, localName);
         }
     }
}

Here the BlockValidation is a singleton instance that is placed into 
each cell along the fo:block row in the table. And the 
BlockValidationContext is a class that hold the state variables for a block.

I have not look at enough of the new validation code to know if my 
approach is powerful enough.

regards,
finn

Re: validateChildNode prevents extensions.

Posted by Glen Mazza <gr...@yahoo.com>.
--- Finn Bock <bc...@worldonline.dk> wrote:
> 
> I don't want to change any FOP code! And if I have
> to change any FOP 
> sources to add an extension, then FOP doesn't
> support extension with the 
> meaning of extension as I understand it.
> 

>From what I understand a program may not change its
own source code while it is running so we may not have
complete freedom for everything.

> An extension mechanism where I can put an unmodified
> fop.jar and 
> myextension.jar on the CLASSPATH and have it work is
> a defining issue to 
> me.  

OK, this looks like a nice feature to have, and the
modifications made to FOP in this regard can be
helpful to others who have similar work to do.

Here's what I see:

Option #1:

1.) myextension.jar will need a FOElementMapping [1]
subclass that will reroute fo:Block from Block.java to
FinnBlock.java.  Have FinnBlock.java override the
vCN() for the new validation rules.  

(FinnBlock.java can also override addLayoutManager()
if it uses a different one--let's discuss this one if
it is an adequate substitute for your need for the LM
makers we were discussing earlier.)

Ideally, myextension.FinnFOElementMapping can subclass
 FOElementMapping so you will only need to define
makers for the elements you are changing.

2.) FOUserAgent.addElementMapping() [2] is the
interface to add an element mapping to runtime FOP. 
Embedded users wanting to link in your library in
their code will need to call
foUserAgent.addElementMapping("myextension.fo.FinnFOElementMapping");

3.) FOTreeBuilder currently loads the "default"
mappers first, then checks for any user-added ones
[3].  We will need to change this logic to have FOP
first load any user-defined (or run-time discovered)
element mappings first, then load each of the default
ones *if* its namespace hasn't already been loaded. 
So for the user adding FinnFOElementMapping with the
XSL namespace URI, this will result in
FOElementMapping *not* being loaded, because it has
the same namespace URI.

4.) (If applicable) Finally, for command-line users,
subclass apps.Fop java, changing both constructors to
load your element mapping: 
foUserAgent.addElementMapping("FinnFOElementMapping"),
and provide a finnfop.bat/.sh that will call this.

Option #2:

1.) Same as #1 above.

2.) Provide a subclass of FOTreeBuilder in my
extension.java that overrides the method
setupDefaultMapping() to load FinnFOElementMapping
instead of FOElementMapping.

3.) Same as #4 above.

Thoughts?

Glen

[1]
http://cvs.apache.org/viewcvs.cgi/xml-fop/src/java/org/apache/fop/fo/FOElementMapping.java?rev=1.8&view=auto

[2]
http://cvs.apache.org/viewcvs.cgi/xml-fop/src/java/org/apache/fop/apps/FOUserAgent.java?annotate=1.15#112

[3]
http://cvs.apache.org/viewcvs.cgi/xml-fop/src/java/org/apache/fop/fo/FOTreeBuilder.java?annotate=1.45#124


Re: validateChildNode prevents extensions.

Posted by Finn Bock <bc...@worldonline.dk>.
>>Extension writers has to create a subclass of
>>AbstractLayoutManager (I 
>>just use a LeafNodeLayoutManager) and an subclass of
>>Area. But that are 
>>normal operations since there are subclasses of
>>those for each element 
>>type. I must also add code to the renderer to handle
>>my area, but that 
>>is because the renderer code is not flexable enough
>>to handle unknown 
>>area classes. I get around that limitation by
>>plugging in a completely 
>>new PDF renderer.

[Glen]

> OK, in other words, you have to change FOP source code
> to add a new XSL-based extension element.  You have no
> problem philosophically with this.

I was unclear. When I write an extension, I make *no* change to any 
existing FOP source files. And I do not replace any existing FOP class 
files with new version.

For an extension element I have to writte a new version of FO classes, a 
layout managers, an area and also a new PDF renderer but these are all 
new files with new class names.

>>Also, I can't replace 
>>the Block class with my subclass in the
>>FOElementMapping without 
>>changing FOP sources.
> 
> OK, you're saying again that you have to change the
> FOP source code in order to add a new XSL-based
> extension element, but now you're having a problem
> with adding *this* code.

I don't want to change any FOP code! And if I have to change any FOP 
sources to add an extension, then FOP doesn't support extension with the 
meaning of extension as I understand it.

> I'm still not sure why this
> is causing you so much more consternation--isn't this
> trivial (even if annoying) to what you will need to do
> in the other classes?

An extension mechanism where I can put an unmodified fop.jar and 
myextension.jar on the CLASSPATH and have it work is a defining issue to 
me. It is the mechanism that is currently paying my rent.

> Between changing code in 3 places with no validation
> for the user community (and tons of NPE/CCE complaints
> due to badly written FO's for the committers to deal
> with on the various lists), vs. changing the code in 4
> or 5 places *with* validation for the user community
> (and few if any NPE/CCE complaints), you do have a bit
> of a tough case to make that the former would win a
> cost-benefit analysis.
> 
> 
>>Having to subclass the parents will prevent two
>>different unrelated 
>>extension from both having fo:block's as parents.
> 
> 
> Not true--fo:block already allows 20 or so different
> types of children--all distinct from each other.  (But
> to further simplify your coding, all you have to do is
> check that the namespace URI is "www.finn.com" or
> whatever and you can choose to allow everything from
> that namespace.)

I meant that if I have to either subclass or change Block.java then two 
independently developed extensions can not both be used in the same 
document.

> Remember, FOP is basically a compiler--like javac, you
> have to define its syntax it will accept, and that
> will require coding.  Also, the only difference
> between an XSL FO and an extension FO is that the
> latter hasn't been blessed by the W3C yet.  Both need
> validation and coding.

I don't mind having to write validation code, but I seriously mind 
having to write it in exsting FOP sources.

>>It has worked quite well before. Without changing
>>any of FOPs layout or 
>>area sources.
> 
> True.  But in the old version, FOP would happily
> accept, say, an fo:root as a child of an fo:block, or
> an fo:layout-master-set as a child of an fo:list-item,
> and subsequently NPE while processing.  That model
> simply had to change.  Nobody would respect/use a
> product that operates that way, or a product based on
> such a product.

Fine, but that can never be an argument for removing support for 
independant extensions.

>>I mean exactly that the validation should be loose.
>>If I need a 
>><finnbock:foobar> tag as a child of fo:block,
>>fo:block should not 
>>prevent me from doing so. 
> 
> 
> Yes it should, if fo:block is to be XSL compliant. 
> The Recommendation defines the content model (i.e.,
> the children) that fo:block is to follow and their
> ordering.  We modify that for the extension elements
> predefined within FOP--as we're allowed to. 

Then I, as an extension writer, also want to change the validation but 
without having to modify existing FOP sources. So the validation have to 
somehow be made plugable.

>>Perhaps the extension elements can implement a tag
>>interface to indicate 
>>that the extension shouldn't be validated by the
>>parent. Or parhaps the 
>>checking could be disabled entirely.
>>
> 
> 
> Actually, we could do that--fairly simple--let's see
> what the other committers have to say.  We can add a
> boolean to FOUserAgent called disableValidation, have
> FOTreeBuilder read it every time it sees an FO in the
> stream, and on the basis of that decide whether or not
> to call vCN().  
> 
> I see two problems though:  (1) performance
> issue--this boolean will need to be read for *every*
> node in the FO document, 

I would guess that a check on a boolean for each node is a bit faster 
than calling vCN for each node. But I have not measured it.

> (2) FOP will be raising NPE
> and CCE errors for invalid FO -- it is strange for a
> program to have a switch that will allow it to blow up
> with errors, or otherwise allow itself to run in an
> invalid state.  Not many programs provide such an
> option--that may not generate much customer
> confidence.  But, again, let's see what others have to
> say.


>>All true, but to an extension writer it doesn't
>>really matter.
>>
> 
> 
> It does, because if FOP keeps blowing up left and
> right, users aren't going to use it (or will be worn
> down by it), committers aren't going to remain with it
> (or potential ones will stay away from it), and the
> progression of FOP will slow down to take care of
> these trivialities.
 >
> You rely on FOP for a lot of the functionality for
> your own work--we need to attract committers in order
> to have more of that.  Also, for people who plan to
> base their work on FOP, i.e., market a derivative of
> it with advanced functionality, it is important that
> FOP have a solid reputation.  If FOP isn't solid,
> people will be less likely to trust derivatives of it,
> even if the extensions are very helpful.

That is all good and fine, but none of it matters to me if FOP doesn't 
support dynamicly loaded extensions.

regards,
finn

Re: validateChildNode prevents extensions.

Posted by Glen Mazza <gr...@yahoo.com>.
--- Finn Bock <bc...@worldonline.dk> wrote:
> 
> Extension writers has to create a subclass of
> AbstractLayoutManager (I 
> just use a LeafNodeLayoutManager) and an subclass of
> Area. But that are 
> normal operations since there are subclasses of
> those for each element 
> type. I must also add code to the renderer to handle
> my area, but that 
> is because the renderer code is not flexable enough
> to handle unknown 
> area classes. I get around that limitation by
> plugging in a completely 
> new PDF renderer.
> 

OK, in other words, you have to change FOP source code
to add a new XSL-based extension element.  You have no
problem philosophically with this.

> Also, I can't replace 
> the Block class with my subclass in the
> FOElementMapping without 
> changing FOP sources.
> 

OK, you're saying again that you have to change the
FOP source code in order to add a new XSL-based
extension element, but now you're having a problem
with adding *this* code.  I'm still not sure why this
is causing you so much more consternation--isn't this
trivial (even if annoying) to what you will need to do
in the other classes?

Between changing code in 3 places with no validation
for the user community (and tons of NPE/CCE complaints
due to badly written FO's for the committers to deal
with on the various lists), vs. changing the code in 4
or 5 places *with* validation for the user community
(and few if any NPE/CCE complaints), you do have a bit
of a tough case to make that the former would win a
cost-benefit analysis.

> Having to subclass the parents will prevent two
> different unrelated 
> extension from both having fo:block's as parents.

Not true--fo:block already allows 20 or so different
types of children--all distinct from each other.  (But
to further simplify your coding, all you have to do is
check that the namespace URI is "www.finn.com" or
whatever and you can choose to allow everything from
that namespace.)

Remember, FOP is basically a compiler--like javac, you
have to define its syntax it will accept, and that
will require coding.  Also, the only difference
between an XSL FO and an extension FO is that the
latter hasn't been blessed by the W3C yet.  Both need
validation and coding.


> > But this shouldn't be a problem, because you have
> to
> > modify the renderers, layout, and/or area objects
> > source code anyway for the extension element to
> work. 
> 
> It has worked quite well before. Without changing
> any of FOPs layout or 
> area sources.
> 

True.  But in the old version, FOP would happily
accept, say, an fo:root as a child of an fo:block, or
an fo:layout-master-set as a child of an fo:list-item,
and subsequently NPE while processing.  That model
simply had to change.  Nobody would respect/use a
product that operates that way, or a product based on
such a product.

> > It's not like you are losing dynamic run-time
> > loadability here, 
> 
> Oh, yes I am.
> 

You will need to better clarify this, because you just
said above that you needed to change source code
anyway to accomodate your new element.

> I mean exactly that the validation should be loose.
> If I need a 
> <finnbock:foobar> tag as a child of fo:block,
> fo:block should not 
> prevent me from doing so. 

Yes it should, if fo:block is to be XSL compliant. 
The Recommendation defines the content model (i.e.,
the children) that fo:block is to follow and their
ordering.  We modify that for the extension elements
predefined within FOP--as we're allowed to.  But it
still has to follow a content model.  The "sit back,
have a beer, and let everything pass through" mode of
validation I'm not too keen on.  ;)

> I promise that I will not
> post the resulting 
> bugs to Bugzilla.
> 

Good, now we'll just need the promises of 500,000
users as well. ;)  You are too smart not to realize
that a non-validating XSL parser is going to generate
lots of NPE/CCE bugs, subtle and otherwise for the
committers and user community to have to deal with. 
Time spent fixing this junk will not be time spent in
the layout and renderers, etc.  That will hurt your
goals, as well as degrade FOP.  

> Perhaps the extension elements can implement a tag
> interface to indicate 
> that the extension shouldn't be validated by the
> parent. Or parhaps the 
> checking could be disabled entirely.
> 

Actually, we could do that--fairly simple--let's see
what the other committers have to say.  We can add a
boolean to FOUserAgent called disableValidation, have
FOTreeBuilder read it every time it sees an FO in the
stream, and on the basis of that decide whether or not
to call vCN().  

I see two problems though:  (1) performance
issue--this boolean will need to be read for *every*
node in the FO document, (2) FOP will be raising NPE
and CCE errors for invalid FO -- it is strange for a
program to have a switch that will allow it to blow up
with errors, or otherwise allow itself to run in an
invalid state.  Not many programs provide such an
option--that may not generate much customer
confidence.  But, again, let's see what others have to
say.


> > The benefits of vCN() is to (1) stop problems at
> the
> > source, prior to creating the node, rather than
> risk
> > many Bugzilla and FOP-User ML messages of subtle
> > NPE/CCE problems that would otherwise occur
> > downstream, and (2) reduce the amount of sometimes
> > duplicative error checking distracting the
> business
> > logic downstream, and (3) provide a uniform
> > error-messaging system.  
> 
> All true, but to an extension writer it doesn't
> really matter.
> 

It does, because if FOP keeps blowing up left and
right, users aren't going to use it (or will be worn
down by it), committers aren't going to remain with it
(or potential ones will stay away from it), and the
progression of FOP will slow down to take care of
these trivialities.

You rely on FOP for a lot of the functionality for
your own work--we need to attract committers in order
to have more of that.  Also, for people who plan to
base their work on FOP, i.e., market a derivative of
it with advanced functionality, it is important that
FOP have a solid reputation.  If FOP isn't solid,
people will be less likely to trust derivatives of it,
even if the extensions are very helpful.

Sorry again for the long post.

Glen


Re: validateChildNode prevents extensions.

Posted by Finn Bock <bc...@worldonline.dk>.
[Glen]

> Extension elements are handled within
> validateChildNode() just like regular formatting
> objects, such as e.g. fox:bookmarks in fo:root [2].  
> 
> We appear to have two categories of extension
> elements:
> 
> 1.) (svg and MathML for example):  These are
> dynamically loadable extension elements that are (1)
> children of fo-instream-foreign-object and (2) don't
> affect layout, renderers, the area tree, etc.

Ok.

> 2.)  (fox:bookmarks, fox:outline, etc.)  These are
> non-runtime-loadable extension elements that work
> directly with formatting objects and whose output must
> be coded within FOP proper.  (fox:bookmarks, for
> example, include logic in area.AreaTreeHandler,
> PDFRenderer perhaps, and additional code in the PDF
> library.) Adding these elements requires not just
> adding an extension element class but additional code
> in layout/renderers/area objects, etc.  

You are IMHO overly focused on the dependencies.

Please note that I have two different roles: FOP developer and extension 
writer. As an extension writer, I can't modify the FOP sources at all.

Extension writers has to create a subclass of AbstractLayoutManager (I 
just use a LeafNodeLayoutManager) and an subclass of Area. But that are 
normal operations since there are subclasses of those for each element 
type. I must also add code to the renderer to handle my area, but that 
is because the renderer code is not flexable enough to handle unknown 
area classes. I get around that limitation by plugging in a completely 
new PDF renderer.

> For these extension elements, they have to be
> validated just like the XSL FO's do:  you have to
> determine which nodes can have these extension
> elements as children, their location, cardinality,
> etc., etc.  So for these elements, you will probably
> need to subclass/rewrite the vCNs() of parents which
> may have them.

Having to subclass the parents will prevent two different unrelated 
extension from both having fo:block's as parents. Also, I can't replace 
the Block class with my subclass in the FOElementMapping without 
changing FOP sources.

> (Of course, once the element is
> directly incorporated into FOP, subclassing will no
> longer be needed.)

The main extension I have in mind can never be incorporated in FOP due 
to licensing.

> But this shouldn't be a problem, because you have to
> modify the renderers, layout, and/or area objects
> source code anyway for the extension element to work. 

It has worked quite well before. Without changing any of FOPs layout or 
area sources.

> It's not like you are losing dynamic run-time
> loadability here, 

Oh, yes I am.

> and generally a vCN() does not add
> much more to the work you have to do.  (Actually,
> vCN() tends to reduce coding complexity of work
> downstream.)

I would have to subclass Block and replace the mapping of <fo:block> to 
my subclass. I didn't have to do any of this before. And I can't do that 
as an extension writer.

>>My guess is that the
>>validation should 
>>only occur when one fo namespace element is added to
>>another fo element.
>>
> 
> 
> I don't think you mean that completely--that's too
> loose.  We should be leery of a system that would
> allow, say, svg:rect to be a child of fo:block.  FOP
> just wouldn't be solid that way, and who would want to
> maintain the Bugzilla list that would result from
> that? ;)

I mean exactly that the validation should be loose. If I need a 
<finnbock:foobar> tag as a child of fo:block, fo:block should not 
prevent me from doing so. I promise that I will not post the resulting 
bugs to Bugzilla.

Perhaps the extension elements can implement a tag interface to indicate 
that the extension shouldn't be validated by the parent. Or parhaps the 
checking could be disabled entirely.

> The benefits of vCN() is to (1) stop problems at the
> source, prior to creating the node, rather than risk
> many Bugzilla and FOP-User ML messages of subtle
> NPE/CCE problems that would otherwise occur
> downstream, and (2) reduce the amount of sometimes
> duplicative error checking distracting the business
> logic downstream, and (3) provide a uniform
> error-messaging system.  

All true, but to an extension writer it doesn't really matter.

>>For instance, Block.validateChildNode() doesn't
>>allow any of my 
>>extension elements as children.
>>
> 
> 
> Yes, you will need to modify it for your new element. 
> But first you have to (1) define which parents your
> element is good for, and (2) where they need to be
> located among those parent's children.  The fact that
> vCN() forces one to stop first and define these things
> is IMO actually a Good Thing, and would have to be
> done anyway should the element be eventually
> incorporated into FOP.
> 
> (BTW, for extension elements that are valid in
> multiple places, take a look at our isBlockItem(),
> isInlineItem() and isNeutralItem() in [3]--you may be
> able to just place your extension elements there if
> they are valid in the same places that the elements
> defined there are.)

regards,
finn

Re: validateChildNode prevents extensions.

Posted by Glen Mazza <gr...@yahoo.com>.
Hello Finn,

[BTW, before I get to this topic, as you've probably
noticed by now I've finished removing the
AddLMVisitor.  In the process, I also created about
eight new layout manager classes, pulling out the
layout business logic that used to be in AddLMVisitor.
 As a result, the maker system you were suggesting
should be MUCH smaller to implement now--probably can
be kept in one class similar to [1].  Would you agree?
 If so, if you still like your suggestion--I don't
care either way--feel free to add such a maker system
in anytime--Simon also was preferring your design.]


--- Finn Bock <bc...@worldonline.dk> wrote:

> Glen
> 
> I think that the new validateChildNode() methods are
> too strict in 
> response to extension elements. 

Extension elements are handled within
validateChildNode() just like regular formatting
objects, such as e.g. fox:bookmarks in fo:root [2].  

We appear to have two categories of extension
elements:

1.) (svg and MathML for example):  These are
dynamically loadable extension elements that are (1)
children of fo-instream-foreign-object and (2) don't
affect layout, renderers, the area tree, etc.  (i.e.,
*no* change to FOP source code is needed in order for
these elements to work.)  FOP, in fo.FOTreeBuilder,
already has a couple of hooks for run-time discovery
and loading of such extension elements.

For these types of extension elements,
validateChildNode() doesn't hurt anything.  The vCN()
in fo-instream-foreign object just enforces, per the
spec, that there is only one child, and that it is in
a non-XSL namespace.

2.)  (fox:bookmarks, fox:outline, etc.)  These are
non-runtime-loadable extension elements that work
directly with formatting objects and whose output must
be coded within FOP proper.  (fox:bookmarks, for
example, include logic in area.AreaTreeHandler,
PDFRenderer perhaps, and additional code in the PDF
library.) Adding these elements requires not just
adding an extension element class but additional code
in layout/renderers/area objects, etc.  

For these extension elements, they have to be
validated just like the XSL FO's do:  you have to
determine which nodes can have these extension
elements as children, their location, cardinality,
etc., etc.  So for these elements, you will probably
need to subclass/rewrite the vCNs() of parents which
may have them.  (Of course, once the element is
directly incorporated into FOP, subclassing will no
longer be needed.)

But this shouldn't be a problem, because you have to
modify the renderers, layout, and/or area objects
source code anyway for the extension element to work. 
It's not like you are losing dynamic run-time
loadability here, and generally a vCN() does not add
much more to the work you have to do.  (Actually,
vCN() tends to reduce coding complexity of work
downstream.)

> My guess is that the
> validation should 
> only occur when one fo namespace element is added to
> another fo element.
> 

I don't think you mean that completely--that's too
loose.  We should be leery of a system that would
allow, say, svg:rect to be a child of fo:block.  FOP
just wouldn't be solid that way, and who would want to
maintain the Bugzilla list that would result from
that? ;)

The benefits of vCN() is to (1) stop problems at the
source, prior to creating the node, rather than risk
many Bugzilla and FOP-User ML messages of subtle
NPE/CCE problems that would otherwise occur
downstream, and (2) reduce the amount of sometimes
duplicative error checking distracting the business
logic downstream, and (3) provide a uniform
error-messaging system.  

> For instance, Block.validateChildNode() doesn't
> allow any of my 
> extension elements as children.
> 

Yes, you will need to modify it for your new element. 
But first you have to (1) define which parents your
element is good for, and (2) where they need to be
located among those parent's children.  The fact that
vCN() forces one to stop first and define these things
is IMO actually a Good Thing, and would have to be
done anyway should the element be eventually
incorporated into FOP.

(BTW, for extension elements that are valid in
multiple places, take a look at our isBlockItem(),
isInlineItem() and isNeutralItem() in [3]--you may be
able to just place your extension elements there if
they are valid in the same places that the elements
defined there are.)

Sorry for the long post.

Glen

[1]
http://cvs.apache.org/viewcvs.cgi/xml-fop/src/java/org/apache/fop/fo/FOElementMapping.java?rev=1.8&view=auto

[2]
http://cvs.apache.org/viewcvs.cgi/xml-fop/src/java/org/apache/fop/fo/pagination/Root.java?annotate=1.23#100

[3]
http://cvs.apache.org/viewcvs.cgi/xml-fop/src/java/org/apache/fop/fo/FObj.java?annotate=1.69#462