01: /*
02: * Copyright (C) 2004, 2005 Joe Walnes.
03: * Copyright (C) 2006, 2007, 2008 XStream Committers.
04: * All rights reserved.
05: *
06: * The software in this package is published under the terms of the BSD
07: * style license a copy of which has been included with this distribution in
08: * the LICENSE.txt file.
09: *
10: * Created on 23. February 2004 by Joe Walnes
11: */
12: package com.thoughtworks.xstream.converters.collections;
13:
14: import com.thoughtworks.xstream.converters.Converter;
15: import com.thoughtworks.xstream.converters.MarshallingContext;
16: import com.thoughtworks.xstream.converters.UnmarshallingContext;
17: import com.thoughtworks.xstream.core.util.Fields;
18: import com.thoughtworks.xstream.io.HierarchicalStreamReader;
19: import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
20:
21: import java.lang.reflect.Field;
22: import java.util.Iterator;
23: import java.util.Map;
24: import java.util.Properties;
25: import java.util.TreeMap;
26:
27: /**
28: * Special converter for java.util.Properties that stores
29: * properties in a more compact form than java.util.Map.
30: * <p/>
31: * <p>Because all entries of a Properties instance
32: * are Strings, a single element is used for each property
33: * with two attributes; one for key and one for value.</p>
34: * <p>Additionally, default properties are also serialized, if they are present.</p>
35: *
36: * @author Joe Walnes
37: * @author Kevin Ring
38: */
39: public class PropertiesConverter implements Converter {
40:
41: private final static Field defaultsField = Fields.find(
42: Properties.class, "defaults");
43: private final boolean sort;
44:
45: public PropertiesConverter() {
46: this (false);
47: }
48:
49: public PropertiesConverter(boolean sort) {
50: this .sort = sort;
51: }
52:
53: public boolean canConvert(Class type) {
54: return Properties.class == type;
55: }
56:
57: public void marshal(Object source, HierarchicalStreamWriter writer,
58: MarshallingContext context) {
59: Properties properties = (Properties) source;
60: Map map = sort ? (Map) new TreeMap(properties)
61: : (Map) properties;
62: for (Iterator iterator = map.entrySet().iterator(); iterator
63: .hasNext();) {
64: Map.Entry entry = (Map.Entry) iterator.next();
65: writer.startNode("property");
66: writer.addAttribute("name", entry.getKey().toString());
67: writer.addAttribute("value", entry.getValue().toString());
68: writer.endNode();
69: }
70: Properties defaults = (Properties) Fields.read(defaultsField,
71: properties);
72: if (defaults != null) {
73: writer.startNode("defaults");
74: marshal(defaults, writer, context);
75: writer.endNode();
76: }
77: }
78:
79: public Object unmarshal(HierarchicalStreamReader reader,
80: UnmarshallingContext context) {
81: Properties properties = new Properties();
82: while (reader.hasMoreChildren()) {
83: reader.moveDown();
84: if (reader.getNodeName().equals("defaults")) {
85: Properties defaults = (Properties) unmarshal(reader,
86: context);
87: Fields.write(defaultsField, properties, defaults);
88: } else {
89: String name = reader.getAttribute("name");
90: String value = reader.getAttribute("value");
91: properties.setProperty(name, value);
92: }
93: reader.moveUp();
94: }
95: return properties;
96: }
97:
98: }
|