Re: validateChildNode prevents extensions.

2004-09-01 Thread Glen Mazza
I see.  Thanks for the explanation.

Glen

--- Finn Bock [EMAIL PROTECTED] 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.

2004-08-31 Thread Finn Bock
[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.

2004-08-29 Thread Finn Bock

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 

Re: validateChildNode prevents extensions.

2004-08-29 Thread J.Pietschmann
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.

2004-08-29 Thread Glen Mazza
--- Finn Bock [EMAIL PROTECTED] 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.8view=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.

2004-08-29 Thread Glen Mazza
--- J.Pietschmann [EMAIL PROTECTED] 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.

2004-08-29 Thread J.Pietschmann
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.

2004-08-29 Thread Glen Mazza
--- Finn Bock [EMAIL PROTECTED] 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.

2004-08-29 Thread Simon Pepping
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.

2004-08-29 Thread Jeremias Maerki

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.

2004-08-28 Thread Glen Mazza

--- Finn Bock [EMAIL PROTECTED] 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.

Re: validateChildNode prevents extensions.

2004-08-27 Thread Glen Mazza
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 [EMAIL PROTECTED] 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.8view=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