From: Joe E. <jo...@em...> - 2006-03-09 02:06:23
|
Rib Rdb wrote: > On 3/7/06, Joe Emenaker <jo...@em...> wrote: > >> Now, granted this is a problem that should only affect someone who's >> authoring a subclass to a implementation of IPatch.... but the >> combination of how easy it would be to forget to call super.write() and >> the consequences for doing so... well... they worry me. >> > > Any problem with serialization, no matter how it happens is going to > cause problems until try to load it. > Well, not necessarily. Before we save any data element to XML, we can make sure (at save time) that the proper method exists for putting that data back into the object. Of course, this doesn't guard against saving to XML, then removing the setter from the class, and then trying to load the XML. But I don't think there's *any* way to solve situations like that. >> My rough idea of the introspection would work something like this: >> - Get a list of all public getters and setters for the object... >> > > This has several problems. For one, the XML setters are not normal > setters: they have to take a string argument. Well, at the present time, all fields of a patch that we're saving (except for the sysex itself) are strings. So, that's not a problem for the *present* situation. Now, as for the future, you pointed out that... > Someone who just writes > a patch class without knowing about serialization is probably not > going to write this type of setter. True. Which is why I said "If any of those getters return anything other than String (or any other data types we know how to save and restore), then throw an exception, or fail, or complain, or do something". In other words, if the author added a getter like "Hashtable getHashtableofsomething()", then the XML saving code would throw up a warning message saying "Hey! We don't know how to save 'java.util.Hashtable', so you're going to lose the data returned by 'getHashtableofsomething()'!". > Also, you lose some flexibility. For example the write method could > do something like this > if (xml.useGzip()) > xml.writeGzippedProperty('gzippedSysex', this.sysex) > else > xml.writeBinaryProperty('sysex', this.sysex) > > And the parser would automatically call the correct setter. If > getters and setters had to be paired, the getter would have to add > some sort of a marker saying whether the data is zipped, and then the > setter would have to split and switch based on that marker. > On the other hand, you could have all gzipping done in the XML code. If a data element is gzipped, you add/change an attribute to the element. <sysex> or <sysex compression="none"> versus <sysex compression="gzip">. You can also set policies in the XML read/write code such as "gzip all String objects longer than 200 bytes". This way, authors of future patch classes don't have to brew their own compression/decompression stuff... and existing patch classes don't have to have the compression code retroactively added. Now, I just thought of another way, which would use your "write()" methods without requiring super.write(). Using inspection, I think it *is* possible to make calls to the over-ridden methods of a superclass. In other words, the XML writing code could call a class' write(), and then call its superclass' write(), and then *that* superclass' superclass' write(), etc.... until it got all the way to the original class. But that's a little spooky. - Joe |