castor

Use of nested class mappings yields invalid mapping file XML

Details

  • Type: Bug Bug
  • Status: Closed Closed
  • Priority: Minor Minor
  • Resolution: Fixed
  • Affects Version/s: 0.9.7
  • Fix Version/s: 1.1
  • Component/s: XML
  • Labels:
    None
  • Environment:
    Windows XP Pro SP2
    Sun J2SDK 1.4.2
    Eclipse 3.1
    XMLBuddy 2.0
    XercesJ 2.7.1
  • Number of attachments :
    2

Description

Using nested class mappings (see http://castor.codehaus.org/xml-mapping.html#3.5-The-%3Cbind-xml%3E-element) to describe the elements of multiple Java Map objects requires specifying several different mappings for the org.exolab.castor.mapping.MapItem class. In the mapping.dtd file, the class name attribute is an ID, and thus can only occur once in an XML file. This results in a fully functional (from Castor's perspective) mapping file that is invalid XML (see example below).

It appears some form of scoping is required, but it's been too long since I've written DTDs for me to propose a robust solution.

Example:

<?xml version="1.0"?>
<!DOCTYPE mapping PUBLIC "-//CODEHAUS/Castor Object Mapping DTD Version 1.0//EN"
"http://castor.codehaus.org/mapping.dtd">

<mapping>
<class name="Foo">
<map-to xml="foo" />

<field name="catalog" collection="map">
<bind-xml name="catalog">
<class name="org.exolab.castor.mapping.MapItem">
<field name="key" type="integer">
<bind-xml name="itemNumber" node="attribute" />
</field>
<field name="value" type="string">
<bind-xml name="itemName" node="attribute" />
</field>
</class>
</bind-xml>
</field>

<field name="personnel" collection="map">
<bind-xml name="personnel">
<class name="org.exolab.castor.mapping.MapItem">
<field name="key" type="integer">
<bind-xml name="idNumber" node="attribute" />
</field>
<field name="value" type="string">
<bind-xml name="name" node="attribute" />
</field>
</class>
</bind-xml>
</field>

</class>
</mapping>

Issue Links

Activity

Hide
Stephen Bash added a comment -

Oops... The hyperlink didn't translate right. Try:
http://castor.codehaus.org/xml-mapping.html#3.5-The-<bind-xml>-element

Show
Stephen Bash added a comment - Oops... The hyperlink didn't translate right. Try: http://castor.codehaus.org/xml-mapping.html#3.5-The-<bind-xml>-element
Hide
Uwe Langbecker added a comment -

The problems seems persist in version 1.1M3. A mapping that worked fine with version 1.0.5 does not work anymore. The problem is related to mapping a class in different ways, dependend on the context, see the attached test case.

I was pointed to this issue. However, I wonder why it used to work in all previous versions of Castor. (1.0.5 and below)

Is there an option to configure that the mapping shall not be validated, either in the Castor properties file or otherwise?

Show
Uwe Langbecker added a comment - The problems seems persist in version 1.1M3. A mapping that worked fine with version 1.0.5 does not work anymore. The problem is related to mapping a class in different ways, dependend on the context, see the attached test case. I was pointed to this issue. However, I wonder why it used to work in all previous versions of Castor. (1.0.5 and below) Is there an option to configure that the mapping shall not be validated, either in the Castor properties file or otherwise?
Hide
Werner Guttmann added a comment -

Uwe, it looks like this has been caused by adding support for validating IDs and IDREFs. Right now, this is a working assumption, but I will use your test case to validate this.

Show
Werner Guttmann added a comment - Uwe, it looks like this has been caused by adding support for validating IDs and IDREFs. Right now, this is a working assumption, but I will use your test case to validate this.
Hide
Werner Guttmann added a comment -

Patch for review. Basically, IDResolverImpl.bind has been modified to take validation mode into account, and the Unmarshaller used to load a mapping file has been set to 'non-validating'.

Show
Werner Guttmann added a comment - Patch for review. Basically, IDResolverImpl.bind has been modified to take validation mode into account, and the Unmarshaller used to load a mapping file has been set to 'non-validating'.
Hide
Ralf Joachim added a comment -

I wonder if validation should be on by default but be configurable through properties file and by a method on Mapping.

Having said that for 1.1 i would include the patch as is and add the configuration with a follow up. Any other opinon?

Show
Ralf Joachim added a comment - I wonder if validation should be on by default but be configurable through properties file and by a method on Mapping. Having said that for 1.1 i would include the patch as is and add the configuration with a follow up. Any other opinon?
Hide
Werner Guttmann added a comment -

Validation was on by default (as per castor.propetrties), and to get past this issue, I had to disable validation on the Unmarshaller used for unmarshalling mapping files. I agree that this could and should be configurable, but the fact that a mapping can include multiple references to the same id ( a custom class name in this case) sort of breaks the algorythm implemented for validating IDs.

I will create a follow-up issue for 1.1.1 to either provide a configurable property, extend Mapping to (dis)allow validation or re-think the solution implemented in IDResolverImpl.

Show
Werner Guttmann added a comment - Validation was on by default (as per castor.propetrties), and to get past this issue, I had to disable validation on the Unmarshaller used for unmarshalling mapping files. I agree that this could and should be configurable, but the fact that a mapping can include multiple references to the same id ( a custom class name in this case) sort of breaks the algorythm implemented for validating IDs. I will create a follow-up issue for 1.1.1 to either provide a configurable property, extend Mapping to (dis)allow validation or re-think the solution implemented in IDResolverImpl.
Hide
Werner Guttmann added a comment -

Patch committed. Please see follow-up issue for any discussions.

Show
Werner Guttmann added a comment - Patch committed. Please see follow-up issue for any discussions.
Hide
Stephen Bash added a comment -

Werner and Ralf - I think turning validation off is a good stop-gap, but in my mind the real issue is we're using IDs in ways that aren't allowed by XML. Very simply if we're going to allow nested class mappings, the class name attribute cannot be an ID. I understand the desire to avoid conflicting top-level mappings, so I'd like to preserve some sort of meta-validation on that (or just an override rule – first or last wins), but true XML validation is also a good thing, and currently we're encouraging people to create non-conforming XML. </rant> Sorry, hope that doesn't come across as too angry, just trying to throw in my US$0.02. Thanks guys for looking into this!

Show
Stephen Bash added a comment - Werner and Ralf - I think turning validation off is a good stop-gap, but in my mind the real issue is we're using IDs in ways that aren't allowed by XML. Very simply if we're going to allow nested class mappings, the class name attribute cannot be an ID. I understand the desire to avoid conflicting top-level mappings, so I'd like to preserve some sort of meta-validation on that (or just an override rule – first or last wins), but true XML validation is also a good thing, and currently we're encouraging people to create non-conforming XML. </rant> Sorry, hope that doesn't come across as too angry, just trying to throw in my US$0.02. Thanks guys for looking into this!
Hide
Werner Guttmann added a comment -

What would you suggest instead of using the class name attribute as an ID ?

Show
Werner Guttmann added a comment - What would you suggest instead of using the class name attribute as an ID ?
Hide
Stephen Bash added a comment -

That's a very interesting question. My first response is to ask how do we use that ID? References (in terms of the HOWTO I wrote) is one thing I can think of, but do they show up elsewhere?

When nested class mapping is thrown into the mix, I think the thing that uniquely identifies the mapping is really the XPath of the element (i.e. I'm referring to catalog/MapItem not personnel/MapItem). I think that causes some problems because XPath really exists at a higher level than ID/IDREF in the XML framework, but I'm fuzzy on that.

Unfortunately I don't have a good solution to the problem, and that's why I hadn't contributed a patch in the past. Attacking the two halves of the problem, we can either change how nested class mappings are specified, or we can change the DTD/schema of the mapping file so that nested class mappings are valid documents.

Thinking about that first option a little bit, maybe we could create some syntactic sugar where nested class mappings are in a <nested-class> element and thus don't conflict with top level <class> elements... Internally they are treated the same way, and there name would again be a problem (I can still have multiple nested class mappings for a single class), but it wouldn't affect the majority of the users that only use top-level class mappings.

Show
Stephen Bash added a comment - That's a very interesting question. My first response is to ask how do we use that ID? References (in terms of the HOWTO I wrote) is one thing I can think of, but do they show up elsewhere? When nested class mapping is thrown into the mix, I think the thing that uniquely identifies the mapping is really the XPath of the element (i.e. I'm referring to catalog/MapItem not personnel/MapItem). I think that causes some problems because XPath really exists at a higher level than ID/IDREF in the XML framework, but I'm fuzzy on that. Unfortunately I don't have a good solution to the problem, and that's why I hadn't contributed a patch in the past. Attacking the two halves of the problem, we can either change how nested class mappings are specified, or we can change the DTD/schema of the mapping file so that nested class mappings are valid documents. Thinking about that first option a little bit, maybe we could create some syntactic sugar where nested class mappings are in a <nested-class> element and thus don't conflict with top level <class> elements... Internally they are treated the same way, and there name would again be a problem (I can still have multiple nested class mappings for a single class), but it wouldn't affect the majority of the users that only use top-level class mappings.
Hide
Werner Guttmann added a comment -

Stephen, let's continue this discussion over at CASTOR-1862, and I'll be committing the patch attached until we find a better solution.

Show
Werner Guttmann added a comment - Stephen, let's continue this discussion over at CASTOR-1862, and I'll be committing the patch attached until we find a better solution.

People

Vote (1)
Watch (1)

Dates

  • Created:
    Updated:
    Resolved:

Time Tracking

Estimated:
1d
Original Estimate - 1 day
Remaining:
1d
Remaining Estimate - 1 day
Logged:
Not Specified
Time Spent - Not Specified