I've modified the mapping-binding.xml to reflect this clarified understanding of the binding file. It is attached.
mapping-binding.xml
Description: Binary data
With Arnaud's fixes to the collection method naming, this binding file now allows source generator to generate the mapping object model in a way that is more consistent with the old xsd_sg way. Remaining differences:
* Enumeration class names are different since the binding file doesn't yet support this.
* The current source generator generates a separate class for xsd:choice elements. This comes into play in the ClassMapping class which contains a multiply-occurring choice between a field element and a container element. In the existing mapping object model ClassMapping contains fields _fieldMappingList and _containerList (and the predictable accessors). In the new source generator, these fields and accessors are in a contained class called ClassChoice. I see four ways to resolve this:
1) Change the mapping object model. I don't know how widely this is used, so I can't say how much this would effect outside users. However, in castor, ClassMapping is explicitly accessed in less than a half-dozen classes outside of the mapping object model. So it would be a relatively minor change (e.g., from clsMap.getFieldMapping() to clsMap.getClassChoice().getFieldMapping()) within castor.
2) Change the mapping.xsd to have, instead of a sequence of choices, a sequence of fieldMappings and a sequence of containers. The problem with this is that you can't express the idea that you have to have at least one of either. But it would result in the "proper" source being generated.
3) Modify source generator to make the generation of the choice class optional. I can't think of a way to do this cleanly, though.
4) Generate ClassMapping as ClassMappingBase instead. Hand-create a subclass (called ClassMapping) which passes calls to getFieldMapping, etc., to the contained ClassChoice. This would require that MappingRoot, etc., be informed to create/accept ClassMappings instead of ClassMappingBase, but I think that the binding file permits this.
So, this fourth option seems most likely to succeed. However, I tried to do it by modifying the binding for "mapping", but the java-type attribute on the member element is not being used the way I'd expect. Here's what I'm trying to do:
<cbf:elementBinding name="mapping">
<cbf:java-class name="MappingRoot"/>
<cbf:elementBinding name="class">
<cbf:member name="classMapping" java-type="ClassMapping"/>
</cbf:elementBinding>
</cbf:elementBinding>
<cbf:elementBinding name="class">
<cbf:java-class name="ClassMappingBase"/>
...
</cbf:elementBinding>
But the MappingRoot#addClassMapping methods are still accepting ClassMappingBase objects and the MappingRoot#getClassMapping methods are returning ClassMappingBase. (Note that I haven't actually created the hand-coded ClassMapping subclass yet, but it doesn't seem like that should matter.) Perhaps this is another facet of the same bug which resulted in the collection-related method names being wrong before?
One more thing:
When defining a custom binding, you can change the name of the generatedThis makes sense to me, but the binding file implementation is not consistent so far as this goes. This is why I was confused. Take mapping-binding.xml as a example. There is a binding for key-generator to specify its class name as KeyGeneratorDef. I did not put in a binding for the key-generator member inside the mapping element, but the accessors for it are generated as getKeyGeneratorDef, etc., just the same. Similarly for the field element within class -- I put in the member binding, but if you take it out the accessors (in ClassChoice) are still generated as getFieldMapping, etc.
class by using the <java-class/> element but this will have NO effect on
the member generated to refer to the generated class.
Thanks for your work and your input.
Rhett
--
Rhett Sutphin
Research Assistant (Software)
Coordinated Laboratory for Computational Genomics
and the Center for Macular Degeneration
University of Iowa - Iowa City, IA 52242 - USA
4111 MEBRF - email: [EMAIL PROTECTED]
On Monday, December 30, 2002, at 10:35 AM, Arnaud Blandin wrote:
Hi Rhett,
It seems that I introduced some confusion in your mind with my answers;
I will try to clarify my thoughts with this post.
When defining a custom binding, you can change the name of the generated
class by using the <java-class/> element but this will have NO effect on
the member generated to refer to the generated class.
To change the name of the member, you have to use the <member/> element
and I thought you were using it. I just fixed the CVS so that now the
methods generated in a collection will reflect the name specified in the
<member/> element.
Concerning your ideas on the enumeration handling, thanks for sharing
that with me; I will make sure I include requests 1) and 2) when
implementing it.
Thanks for all the feedback given and for your willingness to enhance
Castor,
Arnaud
-----Original Message----- From: Rhett Sutphin [mailto:[EMAIL PROTECTED]] Sent: Thursday, December 26, 2002 6:00 PM To: [EMAIL PROTECTED] Subject: Re: [castor-dev] Source Generator & mapping-bindingHi Arnaud, Thanks for your responses. I've got a couple of comments.First the problem reported on the generated method for a collection when using a binding file is surely a bug of the binding file implementation. I will to take a look at it and see what I can do in a small time frame.Thanks for looking at it. But could you clarify what the intended behavior is? For the particular case we are talking about, I'd want the methods to be getClassMapping, etc., but I can see cases where a user might want to change only the name of the class -- not the nameofthe field (or bean property or whatever your want to call it). Is elementBinding/member the place to handle this?Concerning the simpleTypes, you are right it is not handled at allbythe BindingComponent for the moment. If you take a look at the 'binding' XML Schema; you will see a room for defining a custom binding for enumeration.Ah yes, I saw that but I ignored it because it was commented out :). Looking more closely, it seems like it will be very powerful; perhaps even to the point of allowing the user to pick the field names foreachenumerated value? That will be very nice. I don't want to make you regret releasing your work-in-progress code, but I have a couple of things that I hope you'll consider in your implementation that aren't necessarily there in that commented-out block. 1) It would be nice to have user-specifiable int or long values. This will ease integration with JDO, since enumerations in databases are often handled through numeric foreign keys. To make this useful,therewould also need to be generated a valueOf(int) method. (For JDO integration, valueOf(int) would be a worthwhile addition to the source generator, even without the binding file.) 2) For some cases, the enumeration generated by source generator is just fine. So I hope you'll allow just the classname to be specified and have source generator create the enumeration. 3) Much less important: it would be nice if the user could specify the name of the integer value field (and its accessor). So instead oftypeand getType, you could have, say, key and getKey. Even lessimportant,but nice, would be to allow renaming of the the valueOf and toString methods. I suppose I couldn't hurt to be more concrete, so I've attached a modified version of the enum section of binding.xsd that would support these features. (It actually goes a bit further even than these three points.)
