Hi,
I've a situation where I can't currently see how to quite achieve a
requirement I have using XStream as a Java/XML mapper.
The background is we have a UML model off of which we generate Java
classes that are persisted to XML using XStream.
The requirement is that I'd like to apply some default mappings
(mappings as in aliases and converters to influence the way the XML
looks) to an XStream instance, and then pass the instance off to some
other code that can then choose to selectively override those defaults.
The defaults can be applied by either annotations or Java code, I don't
think that matters to the ultimate behaviour of XStream. I'd probably
choose to generate XStream annotations into the generated classes.
In the case of aliases, this works nicely. In my (quite bad) example
below, I've applied defaults using annotations. The test class outputs
the XML produced by the defaults, then I override an alias and output it
again showing that the default has been overridden (the alias is just
overridden in xstream.mapper.ClassAliasingMapper).
This doesn't however work when we choose to use XML attributes rather
than elements. The default for Book.title is an attribute, but there is
no way to override that, once we've set it (there is no way to remove
the field that has been written into
xstream.mapper.AttributeMapper.fieldToUseAsAttribute).
The same issue is there for converters, once set, there is no way to
unset them (no way to remove them from
xstream.mapper.LocalConversionMapper.localConverters).
I can probably figure out ways of achieving this, however so far they
all involve a lot of overriding of XStream classes to change or add
behaviour.
So the first question is, is there a better XStream mechanism to achieve
what I want to do?
If not, would it be a reasonable feature request to allow these sorts of
mappings to be unset on an XStream instance? I think this can be done by
extra API calls on XStream that then unset things on mappers like
AttributeMapper and LocalConversionMapper. For example
XStream.useElementFor methods, XStream.unregisterConverter methods, and
XStream.unregisterLocalConverter methods. XStream.useElementFor for
example would ask AttributeMapper to remove a field from it's internal Set.
What do you think? I look forward to feedback on this.
Output
---------
Defaults give:
<book title="Effective Java: Second Edition" ISBN="0321356683">
<author name="Joshua Bloch"/>
</book>
With overrides gives:
<aBook title="Effective Java: Second Edition" ISBN="0321356683">
<author name="Joshua Bloch"/>
</aBook>
Example code
-------------------
@XStreamAlias("book")
public class Book {
@XStreamAsAttribute
private String title;
@XStreamAsAttribute
private String ISBN;
private Author author;
public String getTitle() {
return this.title;
}
public void setTitle(String name) {
this.title = name;
}
public String getISBN() {
return this.ISBN;
}
public void setISBN(String iSBN) {
this.ISBN = iSBN;
}
public Author getAuthor() {
return this.author;
}
public void setAuthor(Author bar) {
this.author = bar;
}
}
public class Author {
@XStreamAsAttribute
private String name;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
public class BookTest {
public static void main(String[] args) {
Author author = new Author();
author.setName("Joshua Bloch");
Book book = new Book();
book.setTitle("Effective Java: Second Edition");
book.setISBN("0321356683");
book.setAuthor(author);
XStream xstream = new XStream(new PureJavaReflectionProvider(),
new CharacterDataAwareDriver());
xstream.processAnnotations(Book.class);
xstream.processAnnotations(Author.class);
System.err.println("Defaults give: \n");
System.err.println(xstream.toXML(book));
xstream.alias("aBook", Book.class);
System.err.println("\nWith overrides gives: \n");
System.err.println(xstream.toXML(book));
}
}
--
Antony Warner
Software Developer
Gresham Computing PLC
e: [email protected]
w: http://www.gresham-computing.com
Privileged or confidential information may be contained in this message. If you are not the addressee of this message please notify the sender by return and thereafter delete the message, and you may not use, copy, disclose or rely on the information contained in it. Internet e-mail may be susceptible to data corruption, interception and unauthorised amendment for which Gresham does not accept liability. Whilst we have taken reasonable precautions to ensure that this e-mail and any attachments have been swept for viruses, Gresham does not accept liability for any damage sustained as a result of viruses. Statements in this message that do not relate to the business of Gresham are neither given nor endorsed by the company or its directors. Gresham Computing plc Registered in England and Wales. Company No. 01072032 Registered Office: Sopwith House, Brook Avenue, Warsash, Southampton. Hants. SO31 9ZA Further information about Gresham Computing can be found on our website: www.gresham-computing.com