Re: [Simple-support] Creating a "short" serialization
Brought to you by:
niallg
|
From: Ben W. <si...@be...> - 2007-12-17 19:52:07
|
This is a reasonable enough hack, so I think I'll run with it. Thanks! The only concern I have is the object value validation. I'd rather not have to mark all of my elements as "required=false" just to be able to shorten objects down to primary keys. Is there a way to turn off the "required" checking if the @Replace method is invoked? Perhaps a call from the converter to the strategy to confirm whether something needs validation or not. This would all me to use my "Short" serializer for both serializing and deserializing on objects that have the primary keys only filled in but also have some elements marked as "required=true". If the user chooses to deserialize or serialize with the normal serializer, those elements are validated and errors are thrown if they do not have values. Ben Niall Gallagher wrote: > Hi, > > Currently the only ways to use the session Map are the > following: > > Strategy.setRoot // last parameter is the session > Strategy.setElement // last parameter is the session > Strategy.getRoot // last parameter is the session > Strategy.getElement // last parameter is the session > > @Replace > @Resolve > @Persist > @Complete > @Validate > @Commit > > All methods for the above annotations will accept the > session map. I guess the best way to deal with this is > to use the Strategy.setRoot as its called once for the > very first element before anything is persisted. > > Niall > > --- Ben Wolfe <si...@be...> wrote: > >> Using @Persist and @Complete won't work for a few >> reasons. We're using >> a hibernate backend. Modifications to the object >> will make it into the >> database. Adding calls to our 20+ pojos to clear >> out and refill the >> object just isn't plausible. >> >> The @Replace/@Resolve seems to be the best bet. It >> doesn't effect the >> root class -- which is what we want. The only need >> would be to have it >> act conditionally. It looks like the @Replace >> method will take in a >> "Map sessionData" object. Is there a way I can add >> things to that map >> when I create the Persister? Or is the only way to >> modify that map by >> doing so in the @Persist/@Complete/@Replace/@Resolve >> methods? >> >> Thanks, >> Ben >> >> Niall Gallagher wrote: >>> Hi, >>> >>> Take a look at the following unit test. >>> >>> > http://simple.svn.sourceforge.net/viewvc/simple/trunk/download/stream/src/test/java/org/simpleframework/xml/load/SubstituteTest.java >>> This shows the @Replace and @Resolve methods >> working. >>> The reason you could not get your test to run is >>> because the very root Class within the schema >> cannot >>> be replaced, only fields of a composite class. For >>> instance if the class schema you defined was a >> field >>> of some other class then it would replace fine. >>> >>> With respect to you global property suggestion, >> why >>> not just use the session map to pass information >>> about, it will be passed to the @Persist and >> @Complete >>> annotated methods. For example: >>> >>> @Persist >>> private void persistMe(Map session) { >>> // use session here before serialization... >>> } >>> >>> @Complete >>> private void completeMe(Map session) { >>> // use the session here after serialization... >>> } >>> >>> This is just one way, there are tonnes of other >> ways >>> this can be done. >>> >>> Niall >>> >>> --- Ben Wolfe <si...@be...> wrote: >>> >>>> I can't seem to get the Replace method to work. >>>> I've attached a test >>>> method to demonstrate. Perhaps you can show me >> what >>>> I'm doing wrong. :-/ >>>> >>>> The @Replace/@Resolve methods have promise, but I >>>> still don't see a way >>>> for the person serializing to trigger it. The >>>> closest solution would be >>>> if "someProperty" in your example below were >>>> actually a global property >>>> set/retrieved via a call to a util class. >> However, >>>> our code is running >>>> on a server, and it is quite possible that >> multiple >>>> serializations will >>>> be happening at the same time -- some "primary >> key >>>> only" and some full. >>>> >>>> >public Object myResolveMethod() { >>>> > if(someProperty) { >>>> > return new SomeOtherObject(myProperty1, >>>> myProperty2); >>>> > } >>>> > return this; // Here I am saying don't read >>>> resolve >>>> >} >>>> >>>> I have coded up the tags possibility. I can >> submit >>>> a patch if you're >>>> interested. :-) >>>> >>>> Ben >>>> >>>> Niall Gallagher wrote: >>>>> Hi, >>>>> >>>>> Forgot to explain the following code snippit. >> This >>>>> demonstrates how an @Replace method could be >> used >>>>> instead of a @Resolve. The @Replace is used in >>>>> writing, it is similar to Java object >>>> serialization >>>>> writeReplace. >>>>> >>>>> @Root >>>>> public class SomeObject { >>>>> >>>>> @Element(required=false) >>>>> private String text; >>>>> >>>>> @Attribute(required=false) >>>>> private int version; >>>>> >>>>> @Attribute >>>>> private String key; >>>>> >>>>> public SomeObject() { >>>>> super(); >>>>> } >>>>> >>>>> public SomeObject(String key) { >>>>> this.key = key; >>>>> } >>>>> >>>>> @Validate >>>>> public void validate() { >>>>> // do some validation here... >>>>> } >>>>> >>>>> @Replace >>>>> private Object writeReplace() { >>>>> return new SomeObject(key); // Here I >>>> provide >>>>> the same type with a subset of the properties >>>>> } >>>>> } >>>>> >>>>> You could also use the @Persist and @Complete, >> the >>>>> method annotated with @Persist is called just >>>> before >>>>> serialization of the object, and @Complete is >>>> called >>>>> directly after. So you can modify the contents >> of >>>> the >>>>> object before it is serialized and bring the >>>> object >>>>> back to a known state when you have finished >>>>> serializing it. So you get a chance to modify >> the >>>>> object for serialization, there is an example in >>>> the >>>>> tutorial. >>>>> >>>>> Niall >>>>> >>>>> --- Niall Gallagher <gal...@ya...> >>>> wrote: >>>>>> Hi, >>>>>> >>>>>> This will give you both worlds. Why not do the >>>>>> following: >>>>>> >>>>>> public Object myResolveMethod() { >>>>>> if(someProperty) { >>>>>> return new SomeOtherObject(myProperty1, >>>>>> myProperty2); >>>>>> } >>>>>> return this; // Here I am saying don't read >>>>>> resolve >>>>>> } >>>>>> >>>>>> When you return "this" from the method >> annotated >>>>>> with >>>>>> @Resolve annotation you are saying not to >> resolve >>>> to >>>>>> something different. Also, you don't need to >>>> return >>>>>> a >>>>>> different type. >>>>>> >>>>>> >>>>>> @Root >>>>>> public class SomeObject { > === message truncated === > > > > ____________________________________________________________________________________ > Looking for last minute shopping deals? > Find them fast with Yahoo! Search. http://tools.search.yahoo.com/newsearch/category.php?category=shopping |