Decoding XML

From: Kevin Menard (kmenar..ervprise.com)
Date: Wed Mar 09 2005 - 08:43:51 EST

  • Next message: Mike Kienenberger: "Re: Decoding XML"

    So, I started working on a blog post last evening to document the XML
    encoding/decoding features, and stumbled upon a bug. The bug is really
    indicative of a bigger issue surrounding the design of the XML decoding.

    The idea was to have a single arg constructor with a parameter of type
    XMLDecoder to start the decoding, much like the way WebObjects does it.
    Somewhere along the line things started getting mangled. I've never been
    fond of this constructor idea, so I think I moved away from it in the code,
    but not in the design. The result is that with the way I wrote the code,
    something like the following works:

    Reader xml = new FileReader(XML_DATA_DIR + "encoded-object.xml");
    XMLDecoder decoder = new XMLDecoder;
    TestObject object = (TestObject) decoder.decode(xml);

    Compare the above with the following:

    Reader xml = new FileReader(XML_DATA_DIR + "encoded-object.xml");
    XMLDecoder decoder = new XMLDecoder(xml);
    TestObject object = new TestObject(decoder);

    The first case really prods at the XML to fill in property values as best it
    can. It requires a default no-arg constructor however, and the decoded
    values may not quite be what the user wants. The latter should not be much
    of an issue though, assuming the generated XML really models what it's
    supposed to (in this case, the generated XML is coming from an object's
    implementation of encodeAsXML()). Another problem I just came to realize is
    that it assumes in encodeAsXML() that one is only encoding public read/write
    properties, which is wrong, and thus the code is broken.

    The second case really drills home the idea that the XML is driving the
    object creation -- everything is done in the constructor. This of course
    requires an appropriate constructor. It also requires more work on the part
    of the user.

    Of the two, I have been inclined to use the first one, trying to make things
    easier for the user. Part of this is driven by the fact that
    CayenneDataObject has a default implementation for encoding, but no default
    for decoding. The first way of decoding will take care of this case, but
    really fails with others.

    So, I started thinking about it a bit more. Originally, I really wanted to
    make this part of the XMLSerializable interface so there was a clear method
    for decoding. Unfortunately, org.objectstyle.cayenne.util.XMLSerializable,
    which I had built my code around, was an existing interface and I didn't
    want to break the contract provided by it. However, Andrus created a new
    package and a new XMLSerializable interface in it. So, I think it my be a
    better idea to add a decodeXml() method to the interface. In
    CayenneDataObject, I can provide a default implementation as I have with
    encodeAsXml(). And in other cases, the author will have control over the
    decoding, which ought to fix a lot of the problems I've been seeing.

    This approach, of course, does not enforce the decoding at construction, so
    I don't know if that's an issue. It isn't really one for me. Additionally,
    there are cases where one may wish to encode or decode XML, but not both.
    In this case, the code would have to have an empty method implementation for
    the one not being used. Once again, I don't really see this being a
    problem, but I wanted to get thoughts on this before I move ahead with the
    changes.

    If you got this far, thanks. I know it was a bit long-winded, but I wanted
    to provide context with the problem and a possible solution. Any thoughts?

    --
    Kevin



    This archive was generated by hypermail 2.0.0 : Wed Mar 09 2005 - 08:44:46 EST