|
From: Gavin_King/Cirrus%<CI...@ci...> - 2002-02-12 01:32:14
|
Heres my suggested approach to databinding. Everyone feel free to tear it
to shreds :)
First of all, what I'm proposing here is nothing like sun's JAXB standard
which is more of a parser compiler like yacc or ANTLR than an automated
binding of XML to business model classes. I can see where JAXB would be
really really nice (for example in cirrus.hibernate.map) but I can also see
where it isn't really that useful.
There are basically two approaches to databinding:
1. Write an XML schema and generate Java classes from the schema
2. Write your Java classes and generate XML from them
JAXB takes the first approach. I am talking about the second here. Both
approaches usually require a little bit of extra information (a binding
document) to do the translation. Fortunately, Hibernate's persistence
mappings contain *almost* everything we need to generate an XML document
containing the class' persistent state.
Many applications will need the XML delivered in a very particular format.
Rather than trying to anticipate every way of mapping classes to XML
schemas, I propose we initially generate the XML in a very generic format
(that we can write down in a DTD). Then applications can specify (for each
class) an XSLT stylesheet to transform to their chosen format. We can even
provide a "default" stylesheet that will transform to format that would be
useful for many applications.
I've started an experimental branch in CVS called "DATABIND" with some very
rudimentary code along these lines. An example of the generic format is
generated by the test suite:
++++++++++++++++++++++++++++++
<?xml version="1.0" encoding="UTF-8"?>
<hibernate-generic>
<object class="cirrus.hibernate.test.Bar">
<id name="key" type="string">caa3862a:ebf7ca43:00eb:f7ca4d65:0000</id>
<property name="barString" type="string" />
<property name="barComponent" type="component">FooComponent:
bar=69</property>
<property name="time" type="time" />
<property name="foo" type="collection" />
<property name="long" type="long">696969696969696969</property>
<property name="integer" type="integer">-666</property>
<property name="float" type="float">6666.66</property>
<property name="double" type="double">1.33E-69</property>
<property name="bytes" type="collection">[B@3e3d318b</property>
<property name="date" type="date">01 January 1970</property>
<property name="timestamp" type="timestamp">12 February 2002
11:42:24</property>
<property name="boolean" type="boolean">true</property>
<property name="bool" type="boolean">false</property>
<property name="null" type="integer" />
<property name="short" type="short">42</property>
<property name="zero" type="float">0.0</property>
<property name="int" type="integer">2</property>
<property name="string" type="string">a string</property>
<property name="byte" type="byte">127</property>
<property name="yesno" type="yes_no">false</property>
<property name="blob" type
="serializable">cirrus.hibernate.test.Foo$Struct@3e3bf18b</property>
<property name="nullBlob" type="serializable" />
<property name="status" type
="enum">cirrus.hibernate.test.FooStatus@1a42b188</property>
<property name="binary" type="binary">[B@3ec2b18b</property>
<property name="custom" type
="cirrus.hibernate.test.DoubleStringType">foo,bar</property>
<property name="component" type="component">FooComponent: foo=12, Thu
Jan 01 11:00:00 GMT+11:00 1970, Tue Feb 12 11:42:24 GMT+11:00 2002, null,
Tue Feb 12 11:42:24 GMT+11:00 2002 (FooComponent: bar=666, Thu Jan 01
11:02:03 GMT+11:00 1970, null)</property>
</object>
</hibernate-generic>
+++++++++++++++++++++++++++
Clearly that needs some work. Now a default stylesheet could take that and
transform it to:
<Bar>
<key>caa3862a:ebf7ca43:00eb:f7ca4d65:0000</key>
<barString/>
...
<long>696969696969696969</long>
...
<date>01 January 1970</date>
</Bar>
Which is a much more readable format. If that werent good enough, the user
could provide their own stylesheet.
Going backwards (XML->Java object) probably has some extra issues but I
think essentially the same approach could work. Provide a stylesheet to map
to the generic format. Then read Java objects from the generic format.
What does everyone think?
|