Having backward compatible for xstream in the following case
I had the following class.
class SimpleDate {
private final int year; /* ? */
private final int month; /* 0 ~ 11 */
private final int date; /* 1 ~ 31 */
}
Now, I plan to re-factor the class to.
class SimpleDate {
private final int year; /* ? */
private final i开发者_如何转开发nt month; /* 1 ~ 12!!!!! <-- change from 0 based to 1 based */
private final int day; /* 1 ~ 31 */
}
To solve the the variable renaming issues, I will use alias.
xStream.aliasField("date", SimpleDate.class, "day");
However, how can I know I am reading an old XML file, and I will +1 for the newly read month field, to change it from based 0 to based 1?
The xstream FAQ http://x-stream.github.io/faq.html has a section about how tp deal with different versions.
// Converter used to make sure XStream still able to read old version of XML
// files.
private static Converter getSimpleDateConverter() {
return new Converter() {
@Override
public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext mc) {
SimpleDate simpleDate = (SimpleDate) o;
writer.startNode("year");
writer.setValue("" + simpleDate.getYear());
writer.endNode();
writer.startNode("month");
writer.setValue("" + simpleDate.getMonth());
writer.endNode();
writer.startNode("day");
writer.setValue("" + simpleDate.getDay());
writer.endNode();
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext uc) {
Map<String, String> map = new HashMap<String, String>();
while (reader.hasMoreChildren()) {
reader.moveDown();
map.put(reader.getNodeName(), reader.getValue());
reader.moveUp();
}
// Introduce since version 1.0.6.
// We had renamed 'date' field to 'day' field.
final boolean isOldVersion = map.containsKey("date");
if (isOldVersion) {
final int year = Integer.parseInt(map.get("year"));
// We changed 0 based month to 1 based month, to fit into Joda library.
final int month = Integer.parseInt(map.get("month")) + 1;
final int day = Integer.parseInt(map.get("date"));
return new SimpleDate(year, month, day);
} else {
final int year = Integer.parseInt(map.get("year"));
final int month = Integer.parseInt(map.get("month"));
final int day = Integer.parseInt(map.get("day"));
return new SimpleDate(year, month, day);
}
}
@Override
public boolean canConvert(Class type) {
return SimpleDate.class.isAssignableFrom(type);
}
};
}
xStream.registerConverter(getSimpleDateConverter());
精彩评论