You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Don Brown <do...@gmail.com> on 2006/04/23 01:22:27 UTC

[digester] Adding location support

When digester loads in an XML file, the objects created from it have no
concept from where they came, making it difficult to provide accurate and
helpful error messages down the line.

I'd like to add location support for the Digester that would allow a calling
application to capture the source uri, line number, and column number for
every element encountered.  This information could then be used by the
application to provide helpful error messages to their users.  I believe
Howard calls this "Line-precise error reporting".  I've already added this
capability to OpenSymphony's XWork, which powers both WebWork and Struts
Action 2.  I'd like to bring this feature to Struts Action 1 and Commons
Validator, and Digester is the key.

My implementation is borrowed from Apache Cocoon (what good XML technique
isn't ;)) and would be adapted to fit Digester better.  How it works is
this:
 1. Place a ContentHandler filter in between the parser and Digester, which
adds separately-namespeced attributes to each XML element - uri, lineNumber,
and columnNumber.
 2. Then, the user can use the builtin namespace support of Digester to feed
these values into their own Location object and inject it into their
configuration objects in any way they choose.

This technique would leverage Digester's rules to allow the parent
application to have its own Location objects and therefore not require
Digester imports to be scattered throughout their application.  Furthermore,
it would only be enabled if namespace support was enabled, allowing for
complete backwards compatibility.

I am a Jakarta Commons commiter, so I guess I'm asking a) can I join and b)
any objections to me adding this feature?

Don

Re: [digester] Adding location support

Posted by Don Brown <do...@gmail.com>.
I've created the ticket, completed the code and tests, and it all seems to
be working correctly.  The second unit test on
o.a.c.d.pipeline.LocationTransformerTestCase shows how this would most
likely work in reality.

An application would probably define a Location object that has contains the
source uri, the line number, and the column number.  Then, a Locatable
interface that has a single getter/setter for location, would be defined,
allowing configuration objects to implement it.   Then, either the toString
of Location could be included in the toString of the config object, or
exceptions could manually call pull the location out of the config object
and include its info in its message.  The end result is the location
information is now included in all applicable exceptions and messages.

Looking forward to your feedback,

Don

On 4/22/06, Don Brown <do...@gmail.com> wrote:
>
>
>
> On 4/22/06, Simon Kitching <sk...@apache.org> wrote:
> >
> > This feature sounds like an excellent idea to me.
> >
> > I think I would prefer the first few patches to be posted to the list,
> > for feedback before committing them. But assuming everyone's happy with
> > the basic approach/api I'd then personally be happy for you to get stuck
> >
> > in and commit the rest directly.
> >
> > The namespacing approach might need some thought first. Digester's
> > namespace handling for pattern-matching pretty much sucks. This probably
> > isn't relevant here, as that's about matching an ELEMENT using a path,
> > while you are proposing introducing *attributes* with namespaces, not
> > elements that need to be matched by user paths. However I think you
> > *are* relying on CallParamRule(int paramIndex, String attrName) handling
> > namespaces correctly, so the uri/line/column stuff can be fetched, yes?
> > It's therefore necessary to make sure that can indeed be used to handle
> > namespaced data correctly.
>
>
> Ok, I haven't looked into that part yet.  My goal is to make this
> capability as transparent to Digester as possible.  In fact,  the code I
> just wrote implements a (optional) SAX pipeline (ala Cocoon) that allows a
> user to add "Transformers" to modify the SAX events before they hit
> digester.  I'm thinking of the Location injection to be simply a Transformer
> that the user can create and add to the Digester, so the Digester class
> won't even know of its specific existence.
>
> This pipeline opens to doors to greater things, such as multi-schema
> support, meaning the code can be written to one XML schema (schema in its
> generic meaning), but support multiple older schemas through transformations
> that trigger if an older format is detected.  For example, project foo has a
> config file format version 1.  For version 2, they add some elements and
> move things around.  Rather than requiring everyone to use the new format,
> they can just add a transformer that triggers only for version 1 files,
> transforming the XML to meet the new format.  The digester rules never know
> any different.
>
> The pipeline code, as you'll see when I post the patch, only adds 15 or so
> lines to Digester and is itself very small and minimal.
>
> As CallParamsRule, I'm a digester newbie so I'm new to this.  If that rule
> doesn't support namespaces, I'll see what I can do about fixing that.
>
> Don
>

Re: [digester] Adding location support

Posted by Don Brown <do...@gmail.com>.
On 4/22/06, Simon Kitching <sk...@apache.org> wrote:
>
> This feature sounds like an excellent idea to me.
>
> I think I would prefer the first few patches to be posted to the list,
> for feedback before committing them. But assuming everyone's happy with
> the basic approach/api I'd then personally be happy for you to get stuck
> in and commit the rest directly.
>
> The namespacing approach might need some thought first. Digester's
> namespace handling for pattern-matching pretty much sucks. This probably
> isn't relevant here, as that's about matching an ELEMENT using a path,
> while you are proposing introducing *attributes* with namespaces, not
> elements that need to be matched by user paths. However I think you
> *are* relying on CallParamRule(int paramIndex, String attrName) handling
> namespaces correctly, so the uri/line/column stuff can be fetched, yes?
> It's therefore necessary to make sure that can indeed be used to handle
> namespaced data correctly.


Ok, I haven't looked into that part yet.  My goal is to make this capability
as transparent to Digester as possible.  In fact,  the code I just wrote
implements a (optional) SAX pipeline (ala Cocoon) that allows a user to add
"Transformers" to modify the SAX events before they hit digester.  I'm
thinking of the Location injection to be simply a Transformer that the user
can create and add to the Digester, so the Digester class won't even know of
its specific existence.

This pipeline opens to doors to greater things, such as multi-schema
support, meaning the code can be written to one XML schema (schema in its
generic meaning), but support multiple older schemas through transformations
that trigger if an older format is detected.  For example, project foo has a
config file format version 1.  For version 2, they add some elements and
move things around.  Rather than requiring everyone to use the new format,
they can just add a transformer that triggers only for version 1 files,
transforming the XML to meet the new format.  The digester rules never know
any different.

The pipeline code, as you'll see when I post the patch, only adds 15 or so
lines to Digester and is itself very small and minimal.

As CallParamsRule, I'm a digester newbie so I'm new to this.  If that rule
doesn't support namespaces, I'll see what I can do about fixing that.

Don

Re: [digester] Adding location support

Posted by Simon Kitching <sk...@apache.org>.
On Sat, 2006-04-22 at 16:22 -0700, Don Brown wrote:
> When digester loads in an XML file, the objects created from it have no
> concept from where they came, making it difficult to provide accurate and
> helpful error messages down the line.
> 
> I'd like to add location support for the Digester that would allow a calling
> application to capture the source uri, line number, and column number for
> every element encountered.  This information could then be used by the
> application to provide helpful error messages to their users.  I believe
> Howard calls this "Line-precise error reporting".  I've already added this
> capability to OpenSymphony's XWork, which powers both WebWork and Struts
> Action 2.  I'd like to bring this feature to Struts Action 1 and Commons
> Validator, and Digester is the key.
> 
> My implementation is borrowed from Apache Cocoon (what good XML technique
> isn't ;)) and would be adapted to fit Digester better.  How it works is
> this:
>  1. Place a ContentHandler filter in between the parser and Digester, which
> adds separately-namespeced attributes to each XML element - uri, lineNumber,
> and columnNumber.
>  2. Then, the user can use the builtin namespace support of Digester to feed
> these values into their own Location object and inject it into their
> configuration objects in any way they choose.
> 
> This technique would leverage Digester's rules to allow the parent
> application to have its own Location objects and therefore not require
> Digester imports to be scattered throughout their application.  Furthermore,
> it would only be enabled if namespace support was enabled, allowing for
> complete backwards compatibility.
> 
> I am a Jakarta Commons commiter, so I guess I'm asking a) can I join and b)
> any objections to me adding this feature?

This feature sounds like an excellent idea to me.

I think I would prefer the first few patches to be posted to the list,
for feedback before committing them. But assuming everyone's happy with
the basic approach/api I'd then personally be happy for you to get stuck
in and commit the rest directly.

The namespacing approach might need some thought first. Digester's
namespace handling for pattern-matching pretty much sucks. This probably
isn't relevant here, as that's about matching an ELEMENT using a path,
while you are proposing introducing *attributes* with namespaces, not
elements that need to be matched by user paths. However I think you
*are* relying on CallParamRule(int paramIndex, String attrName) handling
namespaces correctly, so the uri/line/column stuff can be fetched, yes?
It's therefore necessary to make sure that can indeed be used to handle
namespaced data correctly.

Or maybe you're proposing a new "GetSourceInfoRule" that can be
associated with an element, and which retrieves the info from the
element attributes for passing (somehow) to a user object?

Anyway, I'm looking forward to seeing details, and would be happy to
help you get this feature into digester (assuming no-one else has any
objections).

Regards,

Simon


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org