Hi Remko, Remko Tronçon wrote:
> Hi, > > I'm having problems parsing/serializing classes to XML that have > values stored in a generic container, such as for example Optional<T> > ( > http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Optional.html > ). When the container is empty (e.g. !Optional.isPresent), i don't want > the field to be serialized at all. > > For example, a field > class Bar { > Optional<String> myField1; > String myField2; > } > would either serialize to: > <bar> > <myField1>Some string</myField1> > <myField2>Some other string</myField2> > <bar> > or to > <bar> > <myField2>Some other string</myField2> > </bar> > depending on whether myField1 contains a value or not. > > Concretely, I have 2 problems: > - If I write a convertor for the Optional type, I don't know what the > right way is to marshal the containing type (basically, I just want to > delegate the serializing further to the default serialization > behavior) Look at the converter tutorial. The last example at the end will do this also. > - A convertor doesn't control the generated tags, so I can't omit > fields from the convertor. I also can't write a mapper, since the > condition on whether to omit an element is based on the actual value > of the object, and as far as i can tell, the check is based on static > type information only. This problem is less crucial than the previous > one, since I suppose i can work around this by writing a filter to > strip empty elements from XML. Actually XStream works only on the structure of the objects, never on the values itself. If you write your own converter, you're free to do so, but - as you have already recognized - you would need one for every type that contains an Optional. I am aware that this is not what you want. > Any suggestions? Since I assume, that your type containing the Optional is currently handled by one of XStream's reflection-based converters, you may use following non- obvious approach by wrapping the ReflectionProvider: ================ %< ============== ReflectionProvider reflectionProvider = new ObjectFilteringReflectionProvider( new JVM().bestReflectionProvider()); XStream xstream = new XStream(reflectionProvider); ... class ObjectFilteringReflectionProvider extends ReflectionProviderWrapper { public ObjectFilteringReflectionProvider(ReflectionProvider wrapped) { super(wrapped); } public void visitSerializableFields( final Object object, final Visitor visitor) { wrapped.visitSerializableFields(object, new Visitor() { public void visit( String name, Class type, Class definedIn, Object value) { if (!(value instanceof Optional) || ((Optional)value).orNull() != null) { visitor.visit(name, type, definedIn, value); } } }); } } ================ %< ============== The ReflectionProvider's visitor is used for serialization by all reflection-based converters to visit any field that must be handled by the converter. The wrapper above will now silently drop any Optional-derived type that contains null. I also assume that this is Java to XML only i.e. no deserialization, because those fields containing Optionals referencing null will no longer be initialized. Hope this helps, Jörg --------------------------------------------------------------------- To unsubscribe from this list, please visit: http://xircles.codehaus.org/manage_email
