KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > thoughtworks > xstream > XStream


1 package com.thoughtworks.xstream;
2
3 import com.thoughtworks.xstream.alias.ClassMapper;
4 import com.thoughtworks.xstream.converters.Converter;
5 import com.thoughtworks.xstream.converters.ConverterLookup;
6 import com.thoughtworks.xstream.converters.reflection.ReflectionProvider;
7 import com.thoughtworks.xstream.core.*;
8 import com.thoughtworks.xstream.io.HierarchicalStreamDriver;
9 import com.thoughtworks.xstream.io.HierarchicalStreamReader;
10 import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
11 import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
12 import com.thoughtworks.xstream.io.xml.XppDriver;
13
14 import java.io.Reader JavaDoc;
15 import java.io.StringReader JavaDoc;
16 import java.io.StringWriter JavaDoc;
17 import java.io.Writer JavaDoc;
18
19 /**
20  * Simple facade to XStream library, a Java-XML serialization tool.
21  * <p/>
22  * <p><hr><b>Example</b><blockquote><pre>
23  * XStream xstream = new XStream();
24  * String xml = xstream.toXML(myObject); // serialize to XML
25  * Object myObject2 = xstream.fromXML(xml); // deserialize from XML
26  * </pre></blockquote><hr>
27  * <p/>
28  * <h3>Aliasing classes</h3>
29  * <p/>
30  * <p>To create shorter XML, you can specify aliases for classes using
31  * the <code>alias()</code> method.
32  * For example, you can shorten all occurences of element
33  * <code>&lt;com.blah.MyThing&gt;</code> to
34  * <code>&lt;my-thing&gt;</code> by registering an alias for the class.
35  * <p><hr><blockquote><pre>
36  * xstream.alias("my-thing", MyThing.class);
37  * </pre></blockquote><hr>
38  * <p/>
39  * <h3>Converters</h3>
40  * <p/>
41  * <p>XStream contains a map of {@link com.thoughtworks.xstream.converters.Converter}
42  * instances, each of which acts as a strategy for converting a particular type
43  * of class to XML and back again. Out of the box, XStream contains converters
44  * for most basic types (String, Date, int, boolean, etc) and collections (Map, List,
45  * Set, Properties, etc). For other objects reflection is used to serialize
46  * each field recursively.</p>
47  * <p/>
48  * <p>Extra converters can be registered using the <code>registerConverter()</code>
49  * method. Some non-standard converters are supplied in the
50  * {@link com.thoughtworks.xstream.converters.extended} package and you can create
51  * your own by implementing the {@link com.thoughtworks.xstream.converters.Converter}
52  * interface.</p>
53  * <p/>
54  * <p><hr><b>Example</b><blockquote><pre>
55  * xstream.registerConverter(new SqlTimestampConverter());
56  * xstream.registerConverter(new DynamicProxyConverter());
57  * </pre></blockquote><hr>
58  * <p/>
59  * <h3>Object graphs</h3>
60  * <p/>
61  * <p>XStream has support for object graphs; a deserialized object graph
62  * will keep references intact, including circular references.</p>
63  * <p/>
64  * <p>XStream can signify references in XML using either XPath or IDs. The
65  * mode can be changed using <code>setMode()</code>:</p>
66  * <p/>
67  * <table border="1">
68  * <tr>
69  * <td><code>xstream.setMode(XStream.XPATH_REFERENCES);</code></td>
70  * <td><i>(Default)</i> Uses XPath references to signify duplicate
71  * references. This produces XML with the least clutter.</td>
72  * </tr>
73  * <tr>
74  * <td><code>xstream.setMode(XStream.ID_REFERENCES);</code></td>
75  * <td>Uses ID references to signify duplicate references. In some
76  * scenarios, such as when using hand-written XML, this is
77  * easier to work with.</td>
78  * </tr>
79  * <tr>
80  * <td><code>xstream.setMode(XStream.NO_REFERENCES);</code></td>
81  * <td>This disables object graph support and treats the object
82  * structure like a tree. Duplicate references are treated
83  * as two seperate objects and circular references cause an
84  * exception. This is slightly faster and uses less memory
85  * than the other two modes.</td>
86  * </tr>
87  * </table>
88  *
89  * @author Joe Walnes
90  */

91 public class XStream {
92
93     private HierarchicalStreamDriver hierarchicalStreamDriver;
94     private MarshallingStrategy marshallingStrategy;
95     private ClassMapper classMapper;
96     private DefaultConverterLookup converterLookup;
97
98     public static final int NO_REFERENCES = 1001;
99     public static final int ID_REFERENCES = 1002;
100     public static final int XPATH_REFERENCES = 1003;
101
102     public XStream() {
103         this(JVM.bestReflectionProvider(), new DefaultClassMapper(), new XppDriver());
104     }
105
106     public XStream(HierarchicalStreamDriver hierarchicalStreamDriver) {
107         this(JVM.bestReflectionProvider(), new DefaultClassMapper(), hierarchicalStreamDriver);
108     }
109
110     public XStream(ReflectionProvider reflectionProvider) {
111         this(reflectionProvider, new DefaultClassMapper(), new XppDriver());
112     }
113
114     public XStream(ReflectionProvider reflectionProvider, HierarchicalStreamDriver hierarchicalStreamDriver) {
115         this(reflectionProvider, new DefaultClassMapper(), hierarchicalStreamDriver);
116     }
117
118     public XStream(ReflectionProvider reflectionProvider, ClassMapper classMapper, HierarchicalStreamDriver driver) {
119         this(reflectionProvider, classMapper, driver, "class");
120     }
121
122     public XStream(ReflectionProvider reflectionProvider, ClassMapper classMapper, HierarchicalStreamDriver driver, String JavaDoc classAttributeIdentifier) {
123         this.classMapper = classMapper;
124         this.hierarchicalStreamDriver = driver;
125         setMode(XPATH_REFERENCES);
126         converterLookup = new DefaultConverterLookup(reflectionProvider, classMapper, classAttributeIdentifier);
127         converterLookup.setupDefaults();
128     }
129
130     public void setMarshallingStrategy(MarshallingStrategy marshallingStrategy) {
131         this.marshallingStrategy = marshallingStrategy;
132     }
133
134     /**
135      * Serialize an object to a pretty-printed XML String.
136      */

137     public String JavaDoc toXML(Object JavaDoc obj) {
138         Writer stringWriter = new StringWriter JavaDoc();
139         HierarchicalStreamWriter writer = new PrettyPrintWriter(stringWriter);
140         marshal(obj, writer);
141         return stringWriter.toString();
142     }
143
144     /**
145      * Serialize an object to the given Writer as pretty-printed XML.
146      */

147     public void toXML(Object JavaDoc obj, Writer writer) {
148         marshal(obj, new PrettyPrintWriter(writer));
149     }
150
151     /**
152      * Serialize and object to a hierarchical data structure (such as XML).
153      */

154     public void marshal(Object JavaDoc obj, HierarchicalStreamWriter writer) {
155         marshallingStrategy.marshal(writer, obj, converterLookup, classMapper);
156     }
157
158     /**
159      * Deserialize an object from an XML String.
160      */

161     public Object JavaDoc fromXML(String JavaDoc xml) {
162         return fromXML(new StringReader JavaDoc(xml));
163     }
164
165     /**
166      * Deserialize an object from an XML Reader.
167      */

168     public Object JavaDoc fromXML(Reader xml) {
169         return unmarshal(hierarchicalStreamDriver.createReader(xml), null);
170     }
171
172     /**
173      * Deserialize an object from a hierarchical data structure (such as XML).
174      */

175     public Object JavaDoc unmarshal(HierarchicalStreamReader reader) {
176         return unmarshal(reader, null);
177     }
178
179     /**
180      * Deserialize an object from a hierarchical data structure (such as XML),
181      * populating the fields of the given root object instead of instantiating
182      * a new one.
183      */

184     public Object JavaDoc unmarshal(HierarchicalStreamReader reader, Object JavaDoc root) {
185         return marshallingStrategy.unmarshal(root, reader, converterLookup, classMapper);
186     }
187
188     /**
189      * Alias a Class to a shorter name to be used in XML elements.
190      *
191      * @param elementName Short name
192      * @param type Type to be aliased
193      */

194     public void alias(String JavaDoc elementName, Class JavaDoc type) {
195         converterLookup.alias(elementName, type, type);
196     }
197
198     /**
199      * Alias a Class to a shorter name to be used in XML elements.
200      *
201      * @param elementName Short name
202      * @param type Type to be aliased
203      * @param defaultImplementation Default implementation of type to use if no other specified.
204      */

205     public void alias(String JavaDoc elementName, Class JavaDoc type, Class JavaDoc defaultImplementation) {
206         converterLookup.alias(elementName, type, defaultImplementation);
207     }
208
209     public void registerConverter(Converter converter) {
210         converterLookup.registerConverter(converter);
211     }
212
213     public ClassMapper getClassMapper() {
214         return classMapper;
215     }
216
217     public ConverterLookup getConverterLookup() {
218         return converterLookup;
219     }
220
221     /**
222      * Change mode for dealing with duplicate references.
223      * Valid valuse are <code>XStream.XPATH_REFERENCES</code>,
224      * <code>XStream.ID_REFERENCES</code> and <code>XStream.NO_REFERENCES</code>.
225      *
226      * @see #XPATH_REFERENCES
227      * @see #ID_REFERENCES
228      * @see #NO_REFERENCES
229      */

230     public void setMode(int mode) {
231         switch (mode) {
232             case NO_REFERENCES:
233                 setMarshallingStrategy(new TreeMarshallingStrategy());
234                 break;
235             case ID_REFERENCES:
236                 setMarshallingStrategy(new ReferenceByIdMarshallingStrategy());
237                 break;
238             case XPATH_REFERENCES:
239                 setMarshallingStrategy(new ReferenceByXPathMarshallingStrategy());
240                 break;
241             default:
242                 throw new IllegalArgumentException JavaDoc("Unknown mode : " + mode);
243         }
244     }
245 }
246
Popular Tags