001/*
002 * Persister.java July 2006
003 *
004 * Copyright (C) 2006, Niall Gallagher <niallg@users.sf.net>
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
015 * implied. See the License for the specific language governing 
016 * permissions and limitations under the License.
017 */
018
019package org.simpleframework.xml.core;
020
021import java.io.File;
022import java.io.FileInputStream;
023import java.io.FileOutputStream;
024import java.io.InputStream;
025import java.io.OutputStream;
026import java.io.OutputStreamWriter;
027import java.io.Reader;
028import java.io.StringReader;
029import java.io.Writer;
030import java.util.HashMap;
031import java.util.Map;
032
033import org.simpleframework.xml.Serializer;
034import org.simpleframework.xml.filter.Filter;
035import org.simpleframework.xml.filter.PlatformFilter;
036import org.simpleframework.xml.strategy.Strategy;
037import org.simpleframework.xml.strategy.TreeStrategy;
038import org.simpleframework.xml.stream.Format;
039import org.simpleframework.xml.stream.InputNode;
040import org.simpleframework.xml.stream.NodeBuilder;
041import org.simpleframework.xml.stream.OutputNode;
042import org.simpleframework.xml.transform.Matcher;
043
044/**
045 * The <code>Persister</code> object is used to provide an implementation
046 * of a serializer. This implements the <code>Serializer</code> interface
047 * and enables objects to be persisted and loaded from various sources. 
048 * This implementation makes use of <code>Filter</code> objects to
049 * replace template variables within the source XML document. It is fully
050 * thread safe and can be shared by multiple threads without concerns.
051 * <p>
052 * Deserialization is performed by passing an XML schema class into one
053 * of the <code>read</code> methods along with the source of an XML stream.
054 * The read method then reads the contents of the XML stream and builds
055 * the object using annotations within the XML schema class.
056 * <p>
057 * Serialization is performed by passing an object and an XML stream into
058 * one of the <code>write</code> methods. The serialization process will
059 * use the class of the provided object as the schema class. The object
060 * is traversed and all fields are marshalled to the result stream.
061 *
062 * @author Niall Gallagher
063 * 
064 * @see org.simpleframework.xml.Serializer
065 */ 
066public class Persister implements Serializer {
067   
068   /**
069    * This is used to manage the serialization sessions created/
070    */
071   private final SessionManager manager;
072   
073   /**
074    * This is the strategy object used to load and resolve classes.
075    */ 
076   private final Strategy strategy;
077
078   /**
079    * This support is used to convert the strings encountered.
080    */
081   private final Support support;
082   
083   /**
084    * This object is used to format the the generated XML document.
085    */ 
086   private final Format format;
087   
088   /**
089    * Constructor for the <code>Persister</code> object. This is used
090    * to create a serializer object that will use an empty filter.
091    * This means that template variables will remain unchanged within
092    * the XML document parsed when an object is deserialized.
093    */
094   public Persister() {
095      this(new HashMap());           
096   }
097   
098   /**
099    * Constructor for the <code>Persister</code> object. This is used
100    * to create a serializer object that will use the provided format
101    * instructions. The persister uses the <code>Format</code> object
102    * to structure the generated XML. It determines the indent size
103    * of the document and whether it should contain a prolog.
104    * 
105    * @param format this is used to structure the generated XML
106    */
107   public Persister(Format format) {
108      this(new TreeStrategy(), format);
109   } 
110
111   /**
112    * Constructor for the <code>Persister</code> object. This is used
113    * to create a serializer object that will use a platform filter
114    * object using the overrides within the provided map. This means
115    * that template variables will be replaced firstly with mappings
116    * from within the provided map, followed by system properties. 
117    * 
118    * @param filter this is the map that contains the overrides
119    */
120   public Persister(Map filter) {
121      this(new PlatformFilter(filter));           
122   }
123   
124   /**
125    * Constructor for the <code>Persister</code> object. This is used
126    * to create a serializer object that will use a platform filter
127    * object using the overrides within the provided map. This means
128    * that template variables will be replaced firstly with mappings
129    * from within the provided map, followed by system properties. 
130    * 
131    * @param filter this is the map that contains the overrides
132    * @param format this is the format used to format the documents
133    */
134   public Persister(Map filter, Format format) {
135      this(new PlatformFilter(filter));           
136   }
137        
138   /**
139    * Constructor for the <code>Persister</code> object. This is used
140    * to create a serializer object that will use the provided filter.
141    * This persister will replace all variables encountered when
142    * deserializing an object with mappings found in the filter.
143    * 
144    * @param filter the filter used to replace template variables
145    */
146   public Persister(Filter filter) {
147      this(new TreeStrategy(), filter);
148   }     
149
150   /**
151    * Constructor for the <code>Persister</code> object. This is used
152    * to create a serializer object that will use the provided filter.
153    * This persister will replace all variables encountered when
154    * deserializing an object with mappings found in the filter.
155    * 
156    * @param filter the filter used to replace template variables
157    * @param format this is used to structure the generated XML
158    */
159   public Persister(Filter filter, Format format) {
160      this(new TreeStrategy(), filter, format);
161   }
162   
163   /**
164    * Constructor for the <code>Persister</code> object. This is used
165    * to create a serializer object that will use the provided matcher
166    * for customizable transformations. The <code>Matcher</code> will
167    * enable the persister to determine the correct way to transform
168    * the types that are not annotated and considered primitives.
169    * 
170    * @param matcher this is used to customize the transformations
171    */
172   public Persister(Matcher matcher) {
173      this(new TreeStrategy(), matcher);
174   }  
175   
176   /**
177    * Constructor for the <code>Persister</code> object. This is used
178    * to create a serializer object that will use the provided matcher
179    * for customizable transformations. The <code>Matcher</code> will
180    * enable the persister to determine the correct way to transform
181    * the types that are not annotated and considered primitives.
182    * 
183    * @param matcher this is used to customize the transformations
184    * @param format this is used to structure the generated XML
185    */
186   public Persister(Matcher matcher, Format format) {
187      this(new TreeStrategy(), matcher, format);
188   }  
189
190   /**
191    * Constructor for the <code>Persister</code> object. This is used
192    * to create a serializer object that will use a strategy object. 
193    * This persister will use the provided <code>Strategy</code> to
194    * intercept the XML elements in order to read and write persistent
195    * data, such as the class name or version of the document.
196    * 
197    * @param strategy this is the strategy used to resolve classes
198    */
199   public Persister(Strategy strategy) {
200      this(strategy, new HashMap());
201   }      
202
203   /**
204    * Constructor for the <code>Persister</code> object. This is used
205    * to create a serializer object that will use a strategy object. 
206    * This persister will use the provided <code>Strategy</code> to
207    * intercept the XML elements in order to read and write persistent
208    * data, such as the class name or version of the document.
209    * 
210    * @param strategy this is the strategy used to resolve classes
211    * @param format this is used to structure the generated XML
212    */
213   public Persister(Strategy strategy, Format format) {
214      this(strategy, new HashMap(), format);           
215   }
216   
217   /**
218    * Constructor for the <code>Persister</code> object. This is used
219    * to create a serializer object that will use the provided filter.
220    * This persister will replace all variables encountered when
221    * deserializing an object with mappings found in the filter.
222    * 
223    * @param filter the filter used to replace template variables
224    * @param matcher this is used to customize the transformations
225    */
226   public Persister(Filter filter, Matcher matcher) {
227      this(new TreeStrategy(), filter, matcher);
228   }     
229
230   /**
231    * Constructor for the <code>Persister</code> object. This is used
232    * to create a serializer object that will use the provided filter.
233    * This persister will replace all variables encountered when
234    * deserializing an object with mappings found in the filter.
235    * 
236    * @param filter the filter used to replace template variables
237    * @param matcher this is used to customize the transformations
238    * @param format this is used to structure the generated XML
239    */
240   public Persister(Filter filter, Matcher matcher, Format format) {
241      this(new TreeStrategy(), filter, matcher, format);
242   }
243
244   /**
245    * Constructor for the <code>Persister</code> object. This is used
246    * to create a serializer object that will use a platform filter
247    * object using the overrides within the provided map. This means
248    * that template variables will be replaced firstly with mappings
249    * from within the provided map, followed by system properties. 
250    * <p>
251    * This persister will use the provided <code>Strategy</code> to
252    * intercept the XML elements in order to read and write persistent
253    * data, such as the class name or version of the document.
254    * 
255    * @param strategy this is the strategy used to resolve classes 
256    * @param data this is the map that contains the overrides
257    */
258   public Persister(Strategy strategy, Map data) {
259      this(strategy, new PlatformFilter(data));           
260   }
261 
262   /**
263    * Constructor for the <code>Persister</code> object. This is used
264    * to create a serializer object that will use the provided filter.
265    * This persister will replace all variables encountered when
266    * deserializing an object with mappings found in the filter.
267    * <p>
268    * This persister will use the provided <code>Strategy</code> to
269    * intercept the XML elements in order to read and write persistent
270    * data, such as the class name or version of the document.
271    * 
272    * @param strategy this is the strategy used to resolve classes 
273    * @param data the filter data used to replace template variables
274    * @param format this is used to format the generated XML document
275    */
276   public Persister(Strategy strategy, Map data, Format format) {
277      this(strategy, new PlatformFilter(data), format);
278   }  
279        
280   /**
281    * Constructor for the <code>Persister</code> object. This is used
282    * to create a serializer object that will use the provided filter.
283    * This persister will replace all variables encountered when
284    * deserializing an object with mappings found in the filter.
285    * <p>
286    * This persister will use the provided <code>Strategy</code> to
287    * intercept the XML elements in order to read and write persistent
288    * data, such as the class name or version of the document.
289    * 
290    * @param strategy this is the strategy used to resolve classes 
291    * @param filter the filter used to replace template variables
292    */
293   public Persister(Strategy strategy, Filter filter) {
294      this(strategy, filter, new Format());
295   }   
296   
297   /**
298    * Constructor for the <code>Persister</code> object. This is used
299    * to create a serializer object that will use the provided filter.
300    * This persister will replace all variables encountered when
301    * deserializing an object with mappings found in the filter.
302    * <p>
303    * This persister will use the provided <code>Strategy</code> to
304    * intercept the XML elements in order to read and write persistent
305    * data, such as the class name or version of the document.
306    * 
307    * @param strategy this is the strategy used to resolve classes 
308    * @param filter the filter used to replace template variables
309    * @param format this is used to format the generated XML document
310    */
311   public Persister(Strategy strategy, Filter filter, Format format) {
312      this(strategy, filter, new EmptyMatcher(), format);
313   }  
314   
315   /**
316    * Constructor for the <code>Persister</code> object. This is used
317    * to create a serializer object that will use the provided matcher
318    * for customizable transformations. The <code>Matcher</code> will
319    * enable the persister to determine the correct way to transform
320    * the types that are not annotated and considered primitives.
321    * <p>
322    * This persister will use the provided <code>Strategy</code> to
323    * intercept the XML elements in order to read and write persistent
324    * data, such as the class name or version of the document.
325    * 
326    * @param strategy this is the strategy used to resolve classes 
327    * @param matcher this is used to customize the transformations
328    */
329   public Persister(Strategy strategy, Matcher matcher) {
330      this(strategy, new PlatformFilter(), matcher);
331   }  
332   
333   /**
334    * Constructor for the <code>Persister</code> object. This is used
335    * to create a serializer object that will use the provided matcher
336    * for customizable transformations. The <code>Matcher</code> will
337    * enable the persister to determine the correct way to transform
338    * the types that are not annotated and considered primitives.
339    * <p>
340    * This persister will use the provided <code>Strategy</code> to
341    * intercept the XML elements in order to read and write persistent
342    * data, such as the class name or version of the document.
343    * 
344    * @param strategy this is the strategy used to resolve classes 
345    * @param matcher this is used to customize the transformations
346    * @param format this is used to format the generated XML document
347    */
348   public Persister(Strategy strategy, Matcher matcher, Format format) {
349      this(strategy, new PlatformFilter(), matcher, format);
350   } 
351   
352   /**
353    * Constructor for the <code>Persister</code> object. This is used
354    * to create a serializer object that will use the provided matcher
355    * for customizable transformations. The <code>Matcher</code> will
356    * enable the persister to determine the correct way to transform
357    * the types that are not annotated and considered primitives.
358    * <p>
359    * This persister will use the provided <code>Strategy</code> to
360    * intercept the XML elements in order to read and write persistent
361    * data, such as the class name or version of the document.
362    * 
363    * @param strategy this is the strategy used to resolve classes 
364    * @param matcher this is used to customize the transformations
365    * @param filter the filter used to replace template variables
366    */
367   public Persister(Strategy strategy, Filter filter, Matcher matcher) {
368      this(strategy, filter, matcher, new Format());
369   } 
370   
371   /**
372    * Constructor for the <code>Persister</code> object. This is used
373    * to create a serializer object that will use the provided matcher
374    * for customizable transformations. The <code>Matcher</code> will
375    * enable the persister to determine the correct way to transform
376    * the types that are not annotated and considered primitives.
377    * <p>
378    * This persister will use the provided <code>Strategy</code> to
379    * intercept the XML elements in order to read and write persistent
380    * data, such as the class name or version of the document.
381    * 
382    * @param strategy this is the strategy used to resolve classes 
383    * @param matcher this is used to customize the transformations
384    * @param filter the filter used to replace template variables
385    */
386   public Persister(Strategy strategy, Filter filter, Matcher matcher, Format format) {
387      this.support = new Support(filter, matcher, format);
388      this.manager = new SessionManager();
389      this.strategy = strategy;
390      this.format = format;
391   } 
392   
393   /**
394    * This <code>read</code> method will read the contents of the XML
395    * document from the provided source and convert it into an object
396    * of the specified type. If the XML source cannot be deserialized
397    * or there is a problem building the object graph an exception
398    * is thrown. The instance deserialized is returned.
399    * 
400    * @param type this is the class type to be deserialized from XML
401    * @param source this provides the source of the XML document
402    * 
403    * @return the object deserialized from the XML document 
404    * 
405    * @throws Exception if the object cannot be fully deserialized
406    */
407   public <T> T read(Class<? extends T> type, String source) throws Exception {
408      return read(type, source, true);            
409   }
410   
411   /**
412    * This <code>read</code> method will read the contents of the XML
413    * document from the provided source and convert it into an object
414    * of the specified type. If the XML source cannot be deserialized
415    * or there is a problem building the object graph an exception
416    * is thrown. The instance deserialized is returned.
417    * 
418    * @param type this is the class type to be deserialized from XML
419    * @param source this provides the source of the XML document
420    * 
421    * @return the object deserialized from the XML document 
422    * 
423    * @throws Exception if the object cannot be fully deserialized
424    */
425   public <T> T read(Class<? extends T> type, File source) throws Exception {
426      return read(type, source, true);
427   }
428   
429   /**
430    * This <code>read</code> method will read the contents of the XML
431    * document from the provided source and convert it into an object
432    * of the specified type. If the XML source cannot be deserialized
433    * or there is a problem building the object graph an exception
434    * is thrown. The instance deserialized is returned.
435    * 
436    * @param type this is the class type to be deserialized from XML
437    * @param source this provides the source of the XML document
438    * 
439    * @return the object deserialized from the XML document 
440    * 
441    * @throws Exception if the object cannot be fully deserialized
442    */
443   public <T> T read(Class<? extends T> type, InputStream source) throws Exception {
444      return read(type, source, true);           
445   }
446   
447   /**
448    * This <code>read</code> method will read the contents of the XML
449    * document from the provided source and convert it into an object
450    * of the specified type. If the XML source cannot be deserialized
451    * or there is a problem building the object graph an exception
452    * is thrown. The instance deserialized is returned.
453    * 
454    * @param type this is the class type to be deserialized from XML
455    * @param source this provides the source of the XML document
456    * 
457    * @return the object deserialized from the XML document 
458    * 
459    * @throws Exception if the object cannot be fully deserialized
460    */
461   public <T> T read(Class<? extends T> type, Reader source) throws Exception {
462      return read(type, source, true);
463   }
464   
465   /**
466    * This <code>read</code> method will read the contents of the XML
467    * document from the provided source and convert it into an object
468    * of the specified type. If the XML source cannot be deserialized
469    * or there is a problem building the object graph an exception
470    * is thrown. The instance deserialized is returned.
471    * 
472    * @param type this is the class type to be deserialized from XML
473    * @param source this provides the source of the XML document
474    * 
475    * @return the object deserialized from the XML document 
476    * 
477    * @throws Exception if the object cannot be fully deserialized
478    */
479   public <T> T read(Class<? extends T> type, InputNode source) throws Exception {
480      return read(type, source, true);
481   }
482   
483   /**
484    * This <code>read</code> method will read the contents of the XML
485    * document from the provided source and convert it into an object
486    * of the specified type. If the XML source cannot be deserialized
487    * or there is a problem building the object graph an exception
488    * is thrown. The instance deserialized is returned.
489    * 
490    * @param type this is the class type to be deserialized from XML
491    * @param source this provides the source of the XML document
492    * @param strict this determines whether to read in strict mode
493    * 
494    * @return the object deserialized from the XML document 
495    * 
496    * @throws Exception if the object cannot be fully deserialized
497    */
498   public <T> T read(Class<? extends T> type, String source, boolean strict) throws Exception {
499      return read(type, new StringReader(source), strict);            
500   }
501   
502   /**
503    * This <code>read</code> method will read the contents of the XML
504    * document from the provided source and convert it into an object
505    * of the specified type. If the XML source cannot be deserialized
506    * or there is a problem building the object graph an exception
507    * is thrown. The instance deserialized is returned.
508    * 
509    * @param type this is the class type to be deserialized from XML
510    * @param source this provides the source of the XML document
511    * @param strict this determines whether to read in strict mode
512    * 
513    * @return the object deserialized from the XML document 
514    * 
515    * @throws Exception if the object cannot be fully deserialized
516    */
517   public <T> T read(Class<? extends T> type, File source, boolean strict) throws Exception {
518      InputStream file = new FileInputStream(source);
519      
520      try {
521         return read(type, file, strict);
522      } finally {
523         file.close();          
524      }
525   }
526   
527   /**
528    * This <code>read</code> method will read the contents of the XML
529    * document from the provided source and convert it into an object
530    * of the specified type. If the XML source cannot be deserialized
531    * or there is a problem building the object graph an exception
532    * is thrown. The instance deserialized is returned.
533    * 
534    * @param type this is the class type to be deserialized from XML
535    * @param source this provides the source of the XML document
536    * @param strict this determines whether to read in strict mode
537    * 
538    * @return the object deserialized from the XML document 
539    * 
540    * @throws Exception if the object cannot be fully deserialized
541    */
542   public <T> T read(Class<? extends T> type, InputStream source, boolean strict) throws Exception {
543      return read(type, NodeBuilder.read(source), strict);           
544   }
545   
546   /**
547    * This <code>read</code> method will read the contents of the XML
548    * document from the provided source and convert it into an object
549    * of the specified type. If the XML source cannot be deserialized
550    * or there is a problem building the object graph an exception
551    * is thrown. The instance deserialized is returned.
552    * 
553    * @param type this is the class type to be deserialized from XML
554    * @param source this provides the source of the XML document
555    * @param strict this determines whether to read in strict mode
556    * 
557    * @return the object deserialized from the XML document 
558    * 
559    * @throws Exception if the object cannot be fully deserialized
560    */
561   public <T> T read(Class<? extends T> type, Reader source, boolean strict) throws Exception {
562      return read(type, NodeBuilder.read(source), strict);
563   }
564   
565   /**
566    * This <code>read</code> method will read the contents of the XML
567    * document from the provided source and convert it into an object
568    * of the specified type. If the XML source cannot be deserialized
569    * or there is a problem building the object graph an exception
570    * is thrown. The instance deserialized is returned.
571    * 
572    * @param type this is the class type to be deserialized from XML
573    * @param node this provides the source of the XML document
574    * @param strict this determines whether to read in strict mode
575    * 
576    * @return the object deserialized from the XML document 
577    * 
578    * @throws Exception if the object cannot be fully deserialized
579    */
580   public <T> T read(Class<? extends T> type, InputNode node, boolean strict) throws Exception {
581      Session session = manager.open(strict);
582      
583      try {
584         return read(type, node, session);
585      } finally {
586         manager.close();
587      }
588   }    
589      
590   /**
591    * This <code>read</code> method will read the contents of the XML
592    * document provided and convert it to an object of the specified
593    * type. If the XML document cannot be deserialized or there is a
594    * problem building the object graph an exception is thrown. The
595    * object graph deserialized is returned.
596    * 
597    * @param type this is the XML schema class to be deserialized
598    * @param node this provides the source of the XML document
599    * @param session this is the session used for deserialization
600    * 
601    * @return the object deserialized from the XML document given
602    * 
603    * @throws Exception if the object cannot be fully deserialized
604    */
605   private <T> T read(Class<? extends T> type, InputNode node, Session session) throws Exception {
606      return read(type, node, new Source(strategy, support, session));
607   }
608        
609   /**
610    * This <code>read</code> method will read the contents of the XML
611    * document provided and convert it to an object of the specified
612    * type. If the XML document cannot be deserialized or there is a
613    * problem building the object graph an exception is thrown. The
614    * object graph deserialized is returned.
615    * 
616    * @param type this is the XML schema class to be deserialized
617    * @param node this provides the source of the XML document
618    * @param context the contextual object used for deserialization 
619    * 
620    * @return the object deserialized from the XML document given
621    * 
622    * @throws Exception if the object cannot be fully deserialized
623    */
624   private <T> T read(Class<? extends T> type, InputNode node, Context context) throws Exception {
625      return (T)new Traverser(context).read(node, type);
626   }
627   
628   /**
629    * This <code>read</code> method will read the contents of the XML
630    * document from the provided source and populate the object with
631    * the values deserialized. This is used as a means of injecting an
632    * object with values deserialized from an XML document. If the
633    * XML source cannot be deserialized or there is a problem building
634    * the object graph an exception is thrown.
635    * 
636    * @param value this is the object to deserialize the XML in to
637    * @param source this provides the source of the XML document
638    * 
639    * @return the same instance provided is returned when finished  
640    * 
641    * @throws Exception if the object cannot be fully deserialized
642    */
643   public <T> T read(T value, String source) throws Exception{
644      return read(value, source, true);            
645   }
646        
647   /**
648    * This <code>read</code> method will read the contents of the XML
649    * document from the provided source and populate the object with
650    * the values deserialized. This is used as a means of injecting an
651    * object with values deserialized from an XML document. If the
652    * XML source cannot be deserialized or there is a problem building
653    * the object graph an exception is thrown.
654    * 
655    * @param value this is the object to deserialize the XML in to
656    * @param source this provides the source of the XML document
657    * 
658    * @return the same instance provided is returned when finished 
659    * 
660    * @throws Exception if the object cannot be fully deserialized
661    */
662   public <T> T read(T value, File source) throws Exception{
663      return read(value, source, true);
664   }
665
666   /**
667    * This <code>read</code> method will read the contents of the XML
668    * document from the provided source and populate the object with
669    * the values deserialized. This is used as a means of injecting an
670    * object with values deserialized from an XML document. If the
671    * XML source cannot be deserialized or there is a problem building
672    * the object graph an exception is thrown.
673    * 
674    * @param value this is the object to deserialize the XML in to
675    * @param source this provides the source of the XML document
676    * 
677    * @return the same instance provided is returned when finished 
678    * 
679    * @throws Exception if the object cannot be fully deserialized
680    */
681   public <T> T read(T value, InputStream source) throws Exception{
682      return read(value, source, true);           
683   }
684
685   /**
686    * This <code>read</code> method will read the contents of the XML
687    * document from the provided source and populate the object with
688    * the values deserialized. This is used as a means of injecting an
689    * object with values deserialized from an XML document. If the
690    * XML source cannot be deserialized or there is a problem building
691    * the object graph an exception is thrown.
692    * 
693    * @param value this is the object to deserialize the XML in to
694    * @param source this provides the source of the XML document
695    * 
696    * @return the same instance provided is returned when finished 
697    * 
698    * @throws Exception if the object cannot be fully deserialized
699    */   
700   public <T> T read(T value, Reader source) throws Exception{
701      return read(value, source, true);
702   }   
703   
704   /**
705    * This <code>read</code> method will read the contents of the XML
706    * document from the provided source and populate the object with
707    * the values deserialized. This is used as a means of injecting an
708    * object with values deserialized from an XML document. If the
709    * XML source cannot be deserialized or there is a problem building
710    * the object graph an exception is thrown.
711    * 
712    * @param value this is the object to deserialize the XML in to
713    * @param source this provides the source of the XML document
714    * 
715    * @return the same instance provided is returned when finished 
716    * 
717    * @throws Exception if the object cannot be fully deserialized
718    */ 
719   public <T> T read(T value, InputNode source) throws Exception {
720      return read(value, source, true);
721   }
722   
723   /**
724    * This <code>read</code> method will read the contents of the XML
725    * document from the provided source and populate the object with
726    * the values deserialized. This is used as a means of injecting an
727    * object with values deserialized from an XML document. If the
728    * XML source cannot be deserialized or there is a problem building
729    * the object graph an exception is thrown.
730    * 
731    * @param value this is the object to deserialize the XML in to
732    * @param source this provides the source of the XML document
733    * @param strict this determines whether to read in strict mode
734    * 
735    * @return the same instance provided is returned when finished  
736    * 
737    * @throws Exception if the object cannot be fully deserialized
738    */
739   public <T> T read(T value, String source, boolean strict) throws Exception{
740      return read(value, new StringReader(source), strict);            
741   }
742        
743   /**
744    * This <code>read</code> method will read the contents of the XML
745    * document from the provided source and populate the object with
746    * the values deserialized. This is used as a means of injecting an
747    * object with values deserialized from an XML document. If the
748    * XML source cannot be deserialized or there is a problem building
749    * the object graph an exception is thrown.
750    * 
751    * @param value this is the object to deserialize the XML in to
752    * @param source this provides the source of the XML document
753    * @param strict this determines whether to read in strict mode
754    * 
755    * @return the same instance provided is returned when finished 
756    * 
757    * @throws Exception if the object cannot be fully deserialized
758    */
759   public <T> T read(T value, File source, boolean strict) throws Exception{
760      InputStream file = new FileInputStream(source);
761      
762      try {
763         return read(value, file, strict);
764      }finally {
765         file.close();           
766      }
767   }
768
769   /**
770    * This <code>read</code> method will read the contents of the XML
771    * document from the provided source and populate the object with
772    * the values deserialized. This is used as a means of injecting an
773    * object with values deserialized from an XML document. If the
774    * XML source cannot be deserialized or there is a problem building
775    * the object graph an exception is thrown.
776    * 
777    * @param value this is the object to deserialize the XML in to
778    * @param source this provides the source of the XML document
779    * @param strict this determines whether to read in strict mode
780    * 
781    * @return the same instance provided is returned when finished 
782    * 
783    * @throws Exception if the object cannot be fully deserialized
784    */
785   public <T> T read(T value, InputStream source, boolean strict) throws Exception{
786      return read(value, NodeBuilder.read(source), strict);           
787   }
788
789   /**
790    * This <code>read</code> method will read the contents of the XML
791    * document from the provided source and populate the object with
792    * the values deserialized. This is used as a means of injecting an
793    * object with values deserialized from an XML document. If the
794    * XML source cannot be deserialized or there is a problem building
795    * the object graph an exception is thrown.
796    * 
797    * @param value this is the object to deserialize the XML in to
798    * @param source this provides the source of the XML document
799    * @param strict this determines whether to read in strict mode
800    * 
801    * @return the same instance provided is returned when finished 
802    * 
803    * @throws Exception if the object cannot be fully deserialized
804    */   
805   public <T> T read(T value, Reader source, boolean strict) throws Exception{
806      return read(value, NodeBuilder.read(source), strict);
807   }   
808   
809   /**
810    * This <code>read</code> method will read the contents of the XML
811    * document from the provided source and populate the object with
812    * the values deserialized. This is used as a means of injecting an
813    * object with values deserialized from an XML document. If the
814    * XML source cannot be deserialized or there is a problem building
815    * the object graph an exception is thrown.
816    * 
817    * @param value this is the object to deserialize the XML in to
818    * @param node this provides the source of the XML document
819    * @param strict this determines whether to read in strict mode
820    * 
821    * @return the same instance provided is returned when finished 
822    * 
823    * @throws Exception if the object cannot be fully deserialized
824    */ 
825   public <T> T read(T value, InputNode node, boolean strict) throws Exception {
826      Session session = manager.open(strict);
827      
828      try {
829         return read(value, node, session);
830      }finally {
831         manager.close();
832      }
833   } 
834   
835   /**
836    * This <code>read</code> method will read the contents of the XML
837    * document from the provided source and populate the object with
838    * the values deserialized. This is used as a means of injecting an
839    * object with values deserialized from an XML document. If the
840    * XML source cannot be deserialized or there is a problem building
841    * the object graph an exception is thrown.
842    * 
843    * @param value this is the object to deserialize the XML in to
844    * @param node this provides the source of the XML document
845    * @param session this is the session used for the deserialization
846    * 
847    * @return the same instance provided is returned when finished 
848    * 
849    * @throws Exception if the object cannot be fully deserialized
850    */ 
851   private <T> T read(T value, InputNode node, Session session) throws Exception {
852      return read(value, node, new Source(strategy, support, session));
853   }
854           
855   /**
856    * This <code>read</code> method will read the contents of the XML
857    * document from the provided source and populate the object with
858    * the values deserialized. This is used as a means of injecting an
859    * object with values deserialized from an XML document. If the
860    * XML source cannot be deserialized or there is a problem building
861    * the object graph an exception is thrown.
862    * 
863    * @param value this is the object to deserialize the XML in to
864    * @param node this provides the source of the XML document
865    * @param context the contextual object used for deserialization
866    * 
867    * @return the same instance provided is returned when finished 
868    * 
869    * @throws Exception if the object cannot be fully deserialized
870    */
871   private <T> T read(T value, InputNode node, Context context) throws Exception {
872      return (T)new Traverser(context).read(node, value);
873   }   
874   
875   /**
876    * This <code>validate</code> method will validate the contents of
877    * the XML document against the specified XML class schema. This is
878    * used to perform a read traversal of the class schema such that 
879    * the document can be tested against it. This is preferred to
880    * reading the document as it does not instantiate the objects or
881    * invoke any callback methods, thus making it a safe validation.
882    * 
883    * @param type this is the class type to be validated against XML
884    * @param source this provides the source of the XML document
885    * 
886    * @return true if the document matches the class XML schema 
887    * 
888    * @throws Exception if the class XML schema does not fully match
889    */
890   public boolean validate(Class type, String source) throws Exception {
891      return validate(type, source, true);            
892   }
893   
894   /**
895    * This <code>validate</code> method will validate the contents of
896    * the XML document against the specified XML class schema. This is
897    * used to perform a read traversal of the class schema such that 
898    * the document can be tested against it. This is preferred to
899    * reading the document as it does not instantiate the objects or
900    * invoke any callback methods, thus making it a safe validation.
901    * 
902    * @param type this is the class type to be validated against XML
903    * @param source this provides the source of the XML document
904    * 
905    * @return true if the document matches the class XML schema 
906    * 
907    * @throws Exception if the class XML schema does not fully match
908    */
909   public boolean validate(Class type, File source) throws Exception {
910      return validate(type, source, true);
911   }
912   
913   /**
914    * This <code>validate</code> method will validate the contents of
915    * the XML document against the specified XML class schema. This is
916    * used to perform a read traversal of the class schema such that 
917    * the document can be tested against it. This is preferred to
918    * reading the document as it does not instantiate the objects or
919    * invoke any callback methods, thus making it a safe validation.
920    * 
921    * @param type this is the class type to be validated against XML
922    * @param source this provides the source of the XML document
923    * 
924    * @return true if the document matches the class XML schema 
925    * 
926    * @throws Exception if the class XML schema does not fully match
927    */
928   public boolean validate(Class type, InputStream source) throws Exception {
929      return validate(type, source, true);           
930   }
931   
932   /**
933    * This <code>validate</code> method will validate the contents of
934    * the XML document against the specified XML class schema. This is
935    * used to perform a read traversal of the class schema such that 
936    * the document can be tested against it. This is preferred to
937    * reading the document as it does not instantiate the objects or
938    * invoke any callback methods, thus making it a safe validation.
939    * 
940    * @param type this is the class type to be validated against XML
941    * @param source this provides the source of the XML document
942    * 
943    * @return true if the document matches the class XML schema 
944    * 
945    * @throws Exception if the class XML schema does not fully match
946    */
947   public boolean validate(Class type, Reader source) throws Exception {
948      return validate(type, source, true);
949   }
950   
951   /**
952    * This <code>validate</code> method will validate the contents of
953    * the XML document against the specified XML class schema. This is
954    * used to perform a read traversal of the class schema such that 
955    * the document can be tested against it. This is preferred to
956    * reading the document as it does not instantiate the objects or
957    * invoke any callback methods, thus making it a safe validation.
958    * 
959    * @param type this is the class type to be validated against XML
960    * @param source this provides the source of the XML document
961    * 
962    * @return true if the document matches the class XML schema 
963    * 
964    * @throws Exception if the class XML schema does not fully match
965    */
966   public boolean validate(Class type, InputNode source) throws Exception {
967      return validate(type, source, true);
968   }         
969   
970   /**
971    * This <code>validate</code> method will validate the contents of
972    * the XML document against the specified XML class schema. This is
973    * used to perform a read traversal of the class schema such that 
974    * the document can be tested against it. This is preferred to
975    * reading the document as it does not instantiate the objects or
976    * invoke any callback methods, thus making it a safe validation.
977    * 
978    * @param type this is the class type to be validated against XML
979    * @param source this provides the source of the XML document
980    * @param strict this determines whether to read in strict mode
981    * 
982    * @return true if the document matches the class XML schema 
983    * 
984    * @throws Exception if the class XML schema does not fully match
985    */
986   public boolean validate(Class type, String source, boolean strict) throws Exception {
987      return validate(type, new StringReader(source), strict);            
988   }
989   
990   /**
991    * This <code>validate</code> method will validate the contents of
992    * the XML document against the specified XML class schema. This is
993    * used to perform a read traversal of the class schema such that 
994    * the document can be tested against it. This is preferred to
995    * reading the document as it does not instantiate the objects or
996    * invoke any callback methods, thus making it a safe validation.
997    * 
998    * @param type this is the class type to be validated against XML
999    * @param source this provides the source of the XML document
1000    * @param strict this determines whether to read in strict mode
1001    * 
1002    * @return true if the document matches the class XML schema 
1003    * 
1004    * @throws Exception if the class XML schema does not fully match
1005    */
1006   public boolean validate(Class type, File source, boolean strict) throws Exception {
1007      InputStream file = new FileInputStream(source);
1008      
1009      try {
1010         return validate(type, file, strict);
1011      } finally {
1012         file.close();          
1013      }
1014   }
1015   
1016   /**
1017    * This <code>validate</code> method will validate the contents of
1018    * the XML document against the specified XML class schema. This is
1019    * used to perform a read traversal of the class schema such that 
1020    * the document can be tested against it. This is preferred to
1021    * reading the document as it does not instantiate the objects or
1022    * invoke any callback methods, thus making it a safe validation.
1023    * 
1024    * @param type this is the class type to be validated against XML
1025    * @param source this provides the source of the XML document
1026    * @param strict this determines whether to read in strict mode
1027    * 
1028    * @return true if the document matches the class XML schema 
1029    * 
1030    * @throws Exception if the class XML schema does not fully match
1031    */
1032   public boolean validate(Class type, InputStream source, boolean strict) throws Exception {
1033      return validate(type, NodeBuilder.read(source), strict);           
1034   }
1035   
1036   /**
1037    * This <code>validate</code> method will validate the contents of
1038    * the XML document against the specified XML class schema. This is
1039    * used to perform a read traversal of the class schema such that 
1040    * the document can be tested against it. This is preferred to
1041    * reading the document as it does not instantiate the objects or
1042    * invoke any callback methods, thus making it a safe validation.
1043    * 
1044    * @param type this is the class type to be validated against XML
1045    * @param source this provides the source of the XML document
1046    * @param strict this determines whether to read in strict mode
1047    * 
1048    * @return true if the document matches the class XML schema 
1049    * 
1050    * @throws Exception if the class XML schema does not fully match
1051    */
1052   public boolean validate(Class type, Reader source, boolean strict) throws Exception {
1053      return validate(type, NodeBuilder.read(source), strict);
1054   }
1055   
1056   /**
1057    * This <code>validate</code> method will validate the contents of
1058    * the XML document against the specified XML class schema. This is
1059    * used to perform a read traversal of the class schema such that 
1060    * the document can be tested against it. This is preferred to
1061    * reading the document as it does not instantiate the objects or
1062    * invoke any callback methods, thus making it a safe validation.
1063    * 
1064    * @param type this is the class type to be validated against XML
1065    * @param node this provides the source of the XML document
1066    * @param strict this determines whether to read in strict mode
1067    * 
1068    * @return true if the document matches the class XML schema 
1069    * 
1070    * @throws Exception if the class XML schema does not fully match
1071    */
1072   public boolean validate(Class type, InputNode node, boolean strict) throws Exception {
1073      Session session = manager.open(strict);
1074      
1075      try {
1076         return validate(type, node, session);
1077      }finally {
1078         manager.close();
1079      }
1080   } 
1081   
1082   /**
1083    * This <code>validate</code> method will validate the contents of
1084    * the XML document against the specified XML class schema. This is
1085    * used to perform a read traversal of the class schema such that 
1086    * the document can be tested against it. This is preferred to
1087    * reading the document as it does not instantiate the objects or
1088    * invoke any callback methods, thus making it a safe validation.
1089    * 
1090    * @param type this is the class type to be validated against XML
1091    * @param node this provides the source of the XML document
1092    * @param session this is the session that is used for validation
1093    * 
1094    * @return true if the document matches the class XML schema 
1095    * 
1096    * @throws Exception if the class XML schema does not fully match
1097    */
1098   private boolean validate(Class type, InputNode node, Session session) throws Exception {
1099      return validate(type, node, new Source(strategy, support, session));
1100   } 
1101           
1102   /**
1103    * This <code>validate</code> method will validate the contents of
1104    * the XML document against the specified XML class schema. This is
1105    * used to perform a read traversal of the class schema such that 
1106    * the document can be tested against it. This is preferred to
1107    * reading the document as it does not instantiate the objects or
1108    * invoke any callback methods, thus making it a safe validation.
1109    * 
1110    * @param type this is the class type to be validated against XML
1111    * @param node this provides the source of the XML document
1112    * @param context the contextual object used for deserialization  
1113    * 
1114    * @return true if the document matches the class XML schema 
1115    * 
1116    * @throws Exception if the class XML schema does not fully match
1117    */
1118   private boolean validate(Class type, InputNode node, Context context) throws Exception {
1119      return new Traverser(context).validate(node, type);
1120   }
1121
1122   /**
1123    * This <code>write</code> method will traverse the provided object
1124    * checking for field annotations in order to compose the XML data.
1125    * This uses the <code>getClass</code> method on the object to
1126    * determine the class file that will be used to compose the schema.
1127    * If there is no <code>Root</code> annotation for the class then
1128    * this will throw an exception. The root annotation is the only
1129    * annotation required for an object to be serialized.  
1130    * 
1131    * @param source this is the object that is to be serialized
1132    * @param root this is where the serialized XML is written to
1133    * 
1134    * @throws Exception if the schema for the object is not valid
1135    */
1136   public void write(Object source, OutputNode root) throws Exception {
1137      Session session = manager.open();
1138      
1139      try {
1140         write(source, root, session);
1141      } finally {
1142         manager.close();
1143      }
1144   }
1145
1146   /**
1147    * This <code>write</code> method will traverse the provided object
1148    * checking for field annotations in order to compose the XML data.
1149    * This uses the <code>getClass</code> method on the object to
1150    * determine the class file that will be used to compose the schema.
1151    * If there is no <code>Root</code> annotation for the class then
1152    * this will throw an exception. The root annotation is the only
1153    * annotation required for an object to be serialized.  
1154    * 
1155    * @param source this is the object that is to be serialized
1156    * @param root this is where the serialized XML is written to
1157    * @param session this is the session used for serialization
1158    * 
1159    * @throws Exception if the schema for the object is not valid
1160    */   
1161   private void write(Object source, OutputNode root, Session session)throws Exception {   
1162      write(source, root, new Source(strategy, support, session));
1163   }
1164
1165   /**
1166    * This <code>write</code> method will traverse the provided object
1167    * checking for field annotations in order to compose the XML data.
1168    * This uses the <code>getClass</code> method on the object to
1169    * determine the class file that will be used to compose the schema.
1170    * If there is no <code>Root</code> annotation for the class then
1171    * this will throw an exception. The root annotation is the only
1172    * annotation required for an object to be serialized.  
1173    * 
1174    * @param source this is the object that is to be serialized
1175    * @param context this is a contextual object used for serialization
1176    * 
1177    * @throws Exception if the schema for the object is not valid
1178    */     
1179   private void write(Object source, OutputNode node, Context context) throws Exception {
1180      new Traverser(context).write(node, source);
1181   }
1182   
1183   /**
1184    * This <code>write</code> method will traverse the provided object
1185    * checking for field annotations in order to compose the XML data.
1186    * This uses the <code>getClass</code> method on the object to
1187    * determine the class file that will be used to compose the schema.
1188    * If there is no <code>Root</code> annotation for the class then
1189    * this will throw an exception. The root annotation is the only
1190    * annotation required for an object to be serialized.  
1191    * 
1192    * @param source this is the object that is to be serialized
1193    * @param out this is where the serialized XML is written to
1194    * 
1195    * @throws Exception if the schema for the object is not valid
1196    */  
1197   public void write(Object source, File out) throws Exception {
1198      OutputStream file = new FileOutputStream(out);
1199      
1200      try {
1201         write(source, file);
1202      }finally {
1203         file.close();
1204      }
1205   }
1206   
1207   /**
1208    * This <code>write</code> method will traverse the provided object
1209    * checking for field annotations in order to compose the XML data.
1210    * This uses the <code>getClass</code> method on the object to
1211    * determine the class file that will be used to compose the schema.
1212    * If there is no <code>Root</code> annotation for the class then
1213    * this will throw an exception. The root annotation is the only
1214    * annotation required for an object to be serialized.  
1215    * 
1216    * @param source this is the object that is to be serialized
1217    * @param out this is where the serialized XML is written to
1218    * 
1219    * @throws Exception if the schema for the object is not valid
1220    */   
1221   public void write(Object source, OutputStream out) throws Exception {
1222      write(source, out, "utf-8");
1223   }
1224   
1225   /**
1226    * This <code>write</code> method will traverse the provided object
1227    * checking for field annotations in order to compose the XML data.
1228    * This uses the <code>getClass</code> method on the object to
1229    * determine the class file that will be used to compose the schema.
1230    * If there is no <code>Root</code> annotation for the class then
1231    * this will throw an exception. The root annotation is the only
1232    * annotation required for an object to be serialized.  
1233    * 
1234    * @param source this is the object that is to be serialized
1235    * @param out this is where the serialized XML is written to
1236    * @param charset this is the character encoding to be used
1237    * 
1238    * @throws Exception if the schema for the object is not valid
1239    */  
1240   public void write(Object source, OutputStream out, String charset) throws Exception {
1241      write(source, new OutputStreamWriter(out, charset));
1242   }
1243   
1244   /**
1245    * This <code>write</code> method will traverse the provided object
1246    * checking for field annotations in order to compose the XML data.
1247    * This uses the <code>getClass</code> method on the object to
1248    * determine the class file that will be used to compose the schema.
1249    * If there is no <code>Root</code> annotation for the class then
1250    * this will throw an exception. The root annotation is the only
1251    * annotation required for an object to be serialized.  
1252    * 
1253    * @param source this is the object that is to be serialized
1254    * @param out this is where the serialized XML is written to
1255    * 
1256    * @throws Exception if the schema for the object is not valid
1257    */   
1258   public void write(Object source, Writer out) throws Exception {
1259      write(source, NodeBuilder.write(out, format));
1260   }
1261}