PageRenderTime 27ms CodeModel.GetById 9ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/Prototipo/Servlet/lib/xstream-distribution-1.4.1-bin/xstream-1.4.1/docs/annotations-tutorial.html

http://prototipomemoria.googlecode.com/
HTML | 497 lines | 410 code | 67 blank | 20 comment | 0 complexity | 4e86e726f002cf88a4e37915b4307897 MD5 | raw file
  1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  2<html xmlns="http://www.w3.org/1999/xhtml">
  3<!--
  4 Copyright (C) 2005, 2006 Joe Walnes.
  5 Copyright (C) 2006, 2007, 2008 XStream committers.
  6 All rights reserved.
  7 
  8 The software in this package is published under the terms of the BSD
  9 style license a copy of which has been included with this distribution in
 10 the LICENSE.txt file.
 11 
 12 Created on 29. January 2005 by Joe Walnes
 13 -->
 14    <head>
 15        <title>XStream - Annotations Tutorial</title>
 16        <link rel="stylesheet" type="text/css" href="style.css"/>
 17        
 18    
 19  
 20
 21        <!-- Google analytics -->
 22        <script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
 23        </script>
 24        <script type="text/javascript">
 25          _uacct = "UA-110973-2";
 26          urchinTracker();
 27        </script>
 28
 29    </head>
 30    <body>
 31
 32        <div id="banner">
 33            <a href="index.html"><img id="logo" src="logo.gif" alt="XStream"/></a>
 34        </div>
 35
 36        <div id="center" class="Content2Column">  <!-- Content3Column for index -->
 37            <div id="content">
 38                <h1 class="FirstChild">Annotations Tutorial</h1>
 39
 40                
 41
 42<!-- ...................................................... -->
 43<h2 id="Motivation">Motivation</h2>
 44<p>Sometimes it can get tedious to call all those XStream aliases/register converter methods or you might simply like
 45the new trend on configuring POJOs: Java annotations.</p>
 46<p>This tutorial will show you how to use some of the annotations provided by XStream in order to make configuration
 47easier.  Let's start with a custom Message class:</p>
 48<div class="Source Java"><pre>package com.thoughtworks.xstream;
 49package com.thoughtworks.xstream;
 50public class RendezvousMessage {
 51
 52	private int messageType;
 53	
 54	public RendezvousMessage(int messageType) {
 55		this.messageType = messageType;
 56	}
 57	
 58}</pre></div>
 59<p>Let's code the XStream calls which generate the XML file:</p>
 60<div class="Source Java"><pre>
 61package com.thoughtworks.xstream;
 62public class Tutorial {
 63
 64	public static void main(String[] args) {
 65		XStream stream = new XStream();
 66		RendezvousMessage msg = new RendezvousMessage(15);
 67		System.out.println(stream.toXML(msg));
 68	}
 69
 70}
 71</pre></div>
 72<p>Results in the following XML:</p>
 73<div class="Source Java"><pre>
 74&lt;com.thoughtworks.xstream.RendezvousMessage&gt;
 75  &lt;messageType&gt;15&lt;/messageType&gt;
 76&lt;/com.thoughtworks.xstream.RendezvousMessage&gt;
 77</pre></div>
 78
 79<!-- ...................................................... -->
 80<h2 id="Aliasing">Aliasing Annotation</h2>
 81<p>The most basic annotation is the one responsible for type and field aliasing: @XStreamAlias.  Let's annotate both
 82our type and field and run the tutorial method again:</p>
 83<div class="Source Java"><pre>
 84@XStreamAlias("message")
 85class RendezvousMessage {
 86
 87	@XStreamAlias("type")
 88	private int messageType;
 89	
 90	public RendezvousMessage(int messageType) {
 91		this.messageType = messageType;
 92	}
 93	
 94}
 95</pre></div>
 96<p>In some strange way, the result is the same.  What happened here?  XStream does not read this annotation by default
 97as it would be impossible to deserialize the XML code.  Therefore we need to tell XStream to read the annotations from
 98this type:</p>
 99<div class="Source Java"><pre>
100	public static void main(String[] args) {
101		XStream stream = new XStream();
102		xstream.processAnnotations(RendezvousMessage.class);
103		RendezvousMessage msg = new RendezvousMessage(15);
104		System.out.println(stream.toXML(msg));
105	}
106</pre></div>
107<p>Note that we have called the processAnnotations method of XStream.  This method registers all aliases annotations in
108the XStream instance passed as first argument. You may also use the overloaded version of this method taking an array
109of types.  The resulting XML is now what we have expected:</p>
110<div class="Source Java"><pre>
111&lt;message&gt;
112  &lt;type&gt;15&lt;/type&gt;
113&lt;/message&gt;
114</pre></div>
115<p>If you let XStream process the annotations of a type, it will also process all annotations of the related types i.e.
116all super types, implemented interfaces, the class types of the members and all their generic types.</p>
117
118<!-- ...................................................... -->
119<h2 id="ImplicitCollections">Implicit Collections</h2>
120<p>Let's add a List of content to our RendezvousMessage.  We desire the same functionality obtained with implicit
121collections:</p>
122<div class="Source Java"><pre>
123@XStreamAlias("message")
124class RendezvousMessage {
125
126	@XStreamAlias("type")
127	private int messageType;        
128	
129	private List&lt;String&gt; content;
130	
131	public RendezvousMessage(int messageType, String ... content) {
132		this.messageType = messageType;
133		this.content = Arrays.asList(content);
134	}
135	
136}
137</pre></div>
138<div class="Source Java"><pre>
139	public static void main(String[] args) {
140		XStream stream = new XStream();
141		xstream.processAnnotations(RendezvousMessage.class);
142		RendezvousMessage msg = new RendezvousMessage(15, "firstPart","secondPart");
143		System.out.println(stream.toXML(msg));
144	}
145</pre></div>
146<p>The resulting XML shows the collection name before its elements:</p>
147<div class="Source Java"><pre>
148&lt;message&gt;
149  &lt;type&gt;15&lt;/type&gt;
150  &lt;content class="java.util.Arrays$ArrayList"&gt;
151    &lt;a class="string-array"&gt;
152      &lt;string&gt;firstPart&lt;/string&gt;
153      &lt;string&gt;secondPart&lt;/string&gt;
154    &lt;/a&gt;
155  &lt;/content&gt;
156&lt;/message&gt;
157</pre></div>
158<p>This is not what we desire therefore we will annotate the content list to be recognized as an implicit collection:</p>
159<div class="Source Java"><pre>
160@XStreamAlias("message")
161class RendezvousMessage {
162
163	@XStreamAlias("type")
164	private int messageType;
165
166	@XStreamImplicit
167	private List&lt;String&gt; content;
168
169	public RendezvousMessage(int messageType, String... content) {
170		this.messageType = messageType;
171		this.content = Arrays.asList(content);
172	}
173
174}
175</pre></div>
176<p>Resulting in an XML which ignores the field name (content) of the list:</p>
177<div class="Source Java"><pre>
178&lt;message&gt;
179  &lt;type&gt;15&lt;/type&gt;
180  &lt;a class="string-array"&gt;
181    &lt;string&gt;firstPart&lt;/string&gt;
182    &lt;string&gt;secondPart&lt;/string&gt;
183  &lt;/a&gt;
184&lt;/message&gt;
185</pre></div>
186<p>We are almost there... we still want to remove the 'a' tag, and define each content part with the tag 'part'.  In
187order to do so, let's add another attribute to our implicit collection annotation.  The attribute field defines the
188name of the tag used for data contained inside this collection:</p>
189<div class="Source Java"><pre>
190@XStreamAlias("message")
191class RendezvousMessage {
192
193	@XStreamAlias("type")
194	private int messageType;
195
196	@XStreamImplicit(itemFieldName="part")
197	private List&lt;String&gt; content;
198
199	public RendezvousMessage(int messageType, String... content) {
200		this.messageType = messageType;
201		this.content = Arrays.asList(content);
202	}
203
204}
205</pre></div>
206<p>Resulting in a cleaner XML:</p>
207<div class="Source Java"><pre>
208&lt;message&gt;
209  &lt;type&gt;15&lt;/type&gt;
210  &lt;part&gt;firstPart&lt;/part&gt;
211  &lt;part&gt;secondPart&lt;/part&gt;
212&lt;/message&gt;
213</pre></div>
214
215<p>The implicit annotation can also be used for arrays and maps.  In the latter case you should provide the field name
216of the values that are used as key of the map.</p>
217
218<!-- ...................................................... -->
219<h2 id="LocalConverters">Local Converters</h2>
220<p>Let's create another attribute which defines the timestamp when the message was created:</p>
221<div class="Source Java"><pre>
222@XStreamAlias("message")
223class RendezvousMessage {
224
225	@XStreamAlias("type")
226	private int messageType;
227
228	@XStreamImplicit(itemFieldName="part")
229	private List&lt;String&gt; content;
230	
231	private Calendar created = new GregorianCalendar();
232
233	public RendezvousMessage(int messageType, String... content) {
234		this.messageType = messageType;
235		this.content = Arrays.asList(content);
236	}
237
238}
239</pre></div>
240<p>Resulting in the following xml:</p>
241<div class="Source Java"><pre>
242&lt;message&gt;
243  &lt;type&gt;15&lt;/type&gt;
244  &lt;part&gt;firstPart&lt;/part&gt;
245  &lt;part&gt;secondPart&lt;/part&gt;
246  &lt;created&gt;
247    &lt;time&gt;1154097812245&lt;/time&gt;
248    &lt;timezone&gt;America/Sao_Paulo&lt;/timezone&gt;
249  &lt;/created&gt;
250&lt;/message&gt;
251</pre></div>
252<p>Now we face the following problem:  We want to use a custom converter locally for this Calendar, but only for this
253Calendar, this exact field in this exact type.  Easy... let's annotate it with the custom converter annotation:</p>
254<div class="Source Java"><pre>
255@XStreamAlias("message")
256class RendezvousMessage {
257
258	@XStreamAlias("type")
259	private int messageType;
260
261	@XStreamImplicit(itemFieldName="part")
262	private List&lt;String&gt; content;
263
264	@XStreamConverter(SingleValueCalendarConverter.class)
265	private Calendar created = new GregorianCalendar();
266
267	public RendezvousMessage(int messageType, String... content) {
268		this.messageType = messageType;
269		this.content = Arrays.asList(content);
270	}
271
272}
273</pre></div>
274<p>Let's create the custom converter:</p>
275<div class="Source Java"><pre>
276public class SingleValueCalendarConverter implements Converter {
277
278    public void marshal(Object source, HierarchicalStreamWriter writer,
279            MarshallingContext context) {
280        Calendar calendar = (Calendar) source;
281        writer.setValue(String.valueOf(calendar.getTime().getTime()));
282    }
283
284    public Object unmarshal(HierarchicalStreamReader reader,
285            UnmarshallingContext context) {
286        GregorianCalendar calendar = new GregorianCalendar();
287        calendar.setTime(new Date(Long.parseLong(reader.getValue())));
288        return calendar;
289    }
290
291    public boolean canConvert(Class type) {
292        return type.equals(GregorianCalendar.class);
293    }
294}
295</pre></div>
296<p>And we end up with the converter being used and generating the following XML:</p>
297<div class="Source Java"><pre>
298&lt;message&gt;
299  &lt;type&gt;15&lt;/type&gt;
300  &lt;part&gt;firstPart&lt;/part&gt;
301  &lt;part&gt;secondPart&lt;/part&gt;
302  &lt;created&gt;1154097812245&lt;/created&gt;
303&lt;/message&gt;
304</pre></div>
305
306<!-- ...................................................... -->
307<h2 id="Attributes">Attributes</h2>
308<p>The client may asks for the type tag to be an attribute inside the message tag, as follows:</p>
309<div class="Source Java"><pre>
310&lt;message type="15"&gt;
311  &lt;part&gt;firstPart&lt;/part&gt;
312  &lt;part&gt;secondPart&lt;/part&gt;
313  &lt;created&gt;1154097812245&lt;/created&gt;
314&lt;/message&gt;
315</pre></div>
316<p>All you need to do is add the @XStreamAsAttribute annotation:</p>
317<div class="Source Java"><pre>
318@XStreamAlias("message")
319class RendezvousMessage {
320
321	@XStreamAlias("type")
322   	@XStreamAsAttribute
323	private int messageType;
324
325	@XStreamImplicit(itemFieldName="part")
326	private List&lt;String&gt; content;
327
328	@XStreamConverter(SingleValueCalendarConverter.class)
329	private Calendar created = new GregorianCalendar();
330
331	public RendezvousMessage(int messageType, String... content) {
332		this.messageType = messageType;
333		this.content = Arrays.asList(content);
334	}
335}
336</pre></div>
337
338<!-- ...................................................... -->
339<h2 id="OmitField">Omitting Fields</h2>
340<p>Sometimes a class may contain elements that should not be part of the resulting XML.  In our case we may now drop
341the 'messageType', since we are only interested at the content. This is easy using the @XStreamOmitField annotation:</p>
342<div class="Source Java"><pre>
343@XStreamAlias("message")
344class RendezvousMessage {
345
346   	@XStreamOmitField
347	private int messageType;
348
349	@XStreamImplicit(itemFieldName="part")
350	private List&lt;String&gt; content;
351
352	@XStreamConverter(SingleValueCalendarConverter.class)
353	private Calendar created = new GregorianCalendar();
354
355	public RendezvousMessage(int messageType, String... content) {
356		this.messageType = messageType;
357		this.content = Arrays.asList(content);
358	}
359}
360</pre></div>
361<p>The resulting XML does not contain the type of the message anymore:</p>
362<div class="Source Java"><pre>
363&lt;message&gt;
364  &lt;part&gt;firstPart&lt;/part&gt;
365  &lt;part&gt;secondPart&lt;/part&gt;
366  &lt;created&gt;1154097812245&lt;/created&gt;
367&lt;/message&gt;
368</pre></div>
369
370<!-- ...................................................... -->
371<h2 id="AutoDetect">Auto-detect Annotations</h2>
372<p>Until now we have always told you, that you have to call processAnnotation to configure the XStream instance with
373the present annotations in the different classes.  However, this is only half the truth.  You can run XStream also in a
374lazy mode, where it auto-detects the annotations while processing the object graph and configure the XStream instance
375on-the-fly:</p>
376<div class="Source Java"><pre>
377package com.thoughtworks.xstream;
378public class Tutorial {
379
380	public static void main(String[] args) {
381		XStream stream = new XStream();
382		xstream.autodetectAnnotations(true);
383		RendezvousMessage msg = new RendezvousMessage(15);
384		System.out.println(stream.toXML(msg));
385	}
386
387}
388</pre></div>
389<p>The resulting XML will look as expected!  Nevertheless you have to understand the implications, therefore some words
390of warning:</p>
391<ol>
392<li><strong>Chicken-and-egg problem</strong>
393<p>An XStream instance caches all class types processed for annotations.  Every time XStream converts an object it will
394in auto-detection mode first process the object's type and all the types related (as explained
395<a href="#Aliasing">above</a>). Therefore it is no problem to serialize an object graph into XML, since XStream will
396know of all types in advance.  This is no longer true at deserialization time.  XStream has to know the alias to turn
397it into the proper type, but it can find the annotation for the alias only if it has processed the type in advance.
398Therefore deserialization will fail if the type has not already been processed either by having called XStream's
399processAnnotations method or by already having serialized this type.  However, @XStreamAlias is the only annotation
400that may fail in this case.</p></li>
401<li><strong>Concurrency</strong>
402<p>XStream is not thread-safe while it is configured, thread-safety is only guaranteed during marshalling and
403unmarshalling.  However an annotation is defining a change in configuration that is now applied while object
404marshalling is processed.  Therefore will the auto-detection mode turn XStream's marshalling process in a thread-unsafe
405operation any you may run under certain circumstances into concurrency problems.</p></li>
406<li><strong>Exceptions</strong>
407<p>XStream uses a well-defined exception hierarchy.  Normally an InitializationException is only thrown while XStream
408is configured.  If annotations are processed on the fly they can be thrown obviously also in a marshalling process.</p></li>
409<li><strong>Performance</strong>
410<p>In auto-detection mode XStream will have to examine any unknown class type for annotations.  This will slow down the
411marshalling process until all processed types have been examined once.</p></li>
412</ol>
413<p>Please note, that any call to XStream.processAnnotations will turn off the auto-detection mode.</p>
414
415<!-- ...................................................... -->
416<h2 id="Summary">Summing up</h2>
417<p>The XStream annotations support might help you configuring your class mappings in some ways, as the custom
418configuration will appear in your types, but might not be the solution for other problems, i.e. when you need to map
419the same type to two different XML 'standards'.  Others might claim that the configuration should be clearly stated in
420a Java class and not mixed with your model, its up to you to pick the best approach in your case:  Annotations or
421direct method calls to the XStream instance.  Annotations do not provide more functionality, but may improve
422convenience.</p>
423
424  
425
426                <br/>
427
428            </div>
429        </div>
430
431        <div class="SidePanel" id="left">
432                <div class="MenuGroup">
433                    <h1>Software</h1>
434                    <ul>
435                                <li><a href="index.html">About XStream</a></li>
436                                <li><a href="news.html">News</a></li>
437                                <li><a href="changes.html">Change History</a></li>
438                                <li><a href="versioning.html">About Versioning</a></li>
439                    </ul>
440                </div>
441                <div class="MenuGroup">
442                    <h1>Evaluating XStream</h1>
443                    <ul>
444                                <li><a href="tutorial.html">Two Minute Tutorial</a></li>
445                                <li><a href="graphs.html">Object references</a></li>
446                                <li><a href="manual-tweaking-output.html">Tweaking the Output</a></li>
447                                <li><a href="license.html">License</a></li>
448                                <li><a href="download.html">Download</a></li>
449                                <li><a href="references.html">References</a></li>
450                                <li><a href="parser-benchmarks.html">Parser Benchmarks</a></li>
451                                <li><a href="http://www.ohloh.net/projects/3459">Code Statistics</a></li>
452                    </ul>
453                </div>
454                <div class="MenuGroup">
455                    <h1>Using XStream</h1>
456                    <ul>
457                                <li><a href="architecture.html">Architecture Overview</a></li>
458                                <li><a href="converters.html">Converters</a></li>
459                                <li><a href="faq.html">Frequently Asked Questions</a></li>
460                                <li><a href="list-user.html">Users' Mailing List</a></li>
461                                <li><a href="issues.html">Reporting Issues</a></li>
462                    </ul>
463                </div>
464                <div class="MenuGroup">
465                    <h1>Javadoc</h1>
466                    <ul>
467                                <li><a href="javadoc/index.html">XStream Core</a></li>
468                                <li><a href="hibernate-javadoc/index.html">Hibernate Extensions</a></li>
469                                <li><a href="benchmark-javadoc/index.html">Benchmark Module</a></li>
470                    </ul>
471                </div>
472                <div class="MenuGroup">
473                    <h1>Tutorials</h1>
474                    <ul>
475                                <li><a href="tutorial.html">Two Minute Tutorial</a></li>
476                                <li><a href="alias-tutorial.html">Alias Tutorial</a></li>
477                                <li class="currentLink">Annotations Tutorial</li>
478                                <li><a href="converter-tutorial.html">Converter Tutorial</a></li>
479                                <li><a href="objectstream.html">Object Streams Tutorial</a></li>
480                                <li><a href="persistence-tutorial.html">Persistence API Tutorial</a></li>
481                                <li><a href="json-tutorial.html">JSON Tutorial</a></li>
482                    </ul>
483                </div>
484                <div class="MenuGroup">
485                    <h1>Developing XStream</h1>
486                    <ul>
487                                <li><a href="how-to-contribute.html">How to Contribute</a></li>
488                                <li><a href="list-dev.html">Developers' Mailing List</a></li>
489                                <li><a href="team.html">Development Team</a></li>
490                                <li><a href="repository.html">Source Repository</a></li>
491                                <li><a href="http://bamboo.ci.codehaus.org/browse/XSTREAM">Continuous Integration</a></li>
492                    </ul>
493                </div>
494        </div>
495
496  </body>
497</html>