• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2008, SnakeYAML
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
13  */
14 package org.yaml.snakeyaml;
15 
16 import java.io.IOException;
17 import java.io.InputStream;
18 import java.io.Reader;
19 import java.io.StringReader;
20 import java.io.StringWriter;
21 import java.io.Writer;
22 import java.util.ArrayList;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.NoSuchElementException;
26 import java.util.regex.Pattern;
27 import org.yaml.snakeyaml.DumperOptions.FlowStyle;
28 import org.yaml.snakeyaml.composer.Composer;
29 import org.yaml.snakeyaml.constructor.BaseConstructor;
30 import org.yaml.snakeyaml.constructor.Constructor;
31 import org.yaml.snakeyaml.emitter.Emitable;
32 import org.yaml.snakeyaml.emitter.Emitter;
33 import org.yaml.snakeyaml.error.YAMLException;
34 import org.yaml.snakeyaml.events.Event;
35 import org.yaml.snakeyaml.introspector.BeanAccess;
36 import org.yaml.snakeyaml.nodes.Node;
37 import org.yaml.snakeyaml.nodes.Tag;
38 import org.yaml.snakeyaml.parser.Parser;
39 import org.yaml.snakeyaml.parser.ParserImpl;
40 import org.yaml.snakeyaml.reader.StreamReader;
41 import org.yaml.snakeyaml.reader.UnicodeReader;
42 import org.yaml.snakeyaml.representer.Representer;
43 import org.yaml.snakeyaml.resolver.Resolver;
44 import org.yaml.snakeyaml.serializer.Serializer;
45 
46 /**
47  * Public YAML interface. This class is not thread-safe. Which means that all the methods of the
48  * same instance can be called only by one thread. It is better to create an instance for every YAML
49  * stream.
50  */
51 public class Yaml {
52 
53   protected final Resolver resolver;
54   private String name;
55   protected BaseConstructor constructor;
56   protected Representer representer;
57   protected DumperOptions dumperOptions;
58   protected LoaderOptions loadingConfig;
59 
60   /**
61    * Create Yaml instance.
62    */
Yaml()63   public Yaml() {
64     this(new Constructor(), new Representer(), new DumperOptions(), new LoaderOptions(),
65         new Resolver());
66   }
67 
68   /**
69    * Create Yaml instance.
70    *
71    * @param dumperOptions DumperOptions to configure outgoing objects
72    */
Yaml(DumperOptions dumperOptions)73   public Yaml(DumperOptions dumperOptions) {
74     this(new Constructor(), new Representer(dumperOptions), dumperOptions);
75   }
76 
77   /**
78    * Create Yaml instance.
79    *
80    * @param loadingConfig LoadingConfig to control load behavior
81    */
Yaml(LoaderOptions loadingConfig)82   public Yaml(LoaderOptions loadingConfig) {
83     this(new Constructor(loadingConfig), new Representer(), new DumperOptions(), loadingConfig);
84   }
85 
86   /**
87    * Create Yaml instance.
88    *
89    * @param representer Representer to emit outgoing objects
90    */
Yaml(Representer representer)91   public Yaml(Representer representer) {
92     this(new Constructor(), representer);
93   }
94 
95   /**
96    * Create Yaml instance.
97    *
98    * @param constructor BaseConstructor to construct incoming documents
99    */
Yaml(BaseConstructor constructor)100   public Yaml(BaseConstructor constructor) {
101     this(constructor, new Representer());
102   }
103 
104   /**
105    * Create Yaml instance.
106    *
107    * @param constructor BaseConstructor to construct incoming documents
108    * @param representer Representer to emit outgoing objects
109    */
Yaml(BaseConstructor constructor, Representer representer)110   public Yaml(BaseConstructor constructor, Representer representer) {
111     this(constructor, representer, initDumperOptions(representer));
112   }
113 
initDumperOptions(Representer representer)114   private static DumperOptions initDumperOptions(Representer representer) {
115     DumperOptions dumperOptions = new DumperOptions();
116     dumperOptions.setDefaultFlowStyle(representer.getDefaultFlowStyle());
117     dumperOptions.setDefaultScalarStyle(representer.getDefaultScalarStyle());
118     dumperOptions
119         .setAllowReadOnlyProperties(representer.getPropertyUtils().isAllowReadOnlyProperties());
120     dumperOptions.setTimeZone(representer.getTimeZone());
121     return dumperOptions;
122   }
123 
124   /**
125    * Create Yaml instance. It is safe to create a few instances and use them in different Threads.
126    *
127    * @param representer Representer to emit outgoing objects
128    * @param dumperOptions DumperOptions to configure outgoing objects
129    */
Yaml(Representer representer, DumperOptions dumperOptions)130   public Yaml(Representer representer, DumperOptions dumperOptions) {
131     this(new Constructor(), representer, dumperOptions, new LoaderOptions(), new Resolver());
132   }
133 
134   /**
135    * Create Yaml instance. It is safe to create a few instances and use them in different Threads.
136    *
137    * @param constructor BaseConstructor to construct incoming documents
138    * @param representer Representer to emit outgoing objects
139    * @param dumperOptions DumperOptions to configure outgoing objects
140    */
Yaml(BaseConstructor constructor, Representer representer, DumperOptions dumperOptions)141   public Yaml(BaseConstructor constructor, Representer representer, DumperOptions dumperOptions) {
142     this(constructor, representer, dumperOptions, new LoaderOptions(), new Resolver());
143   }
144 
145   /**
146    * Create Yaml instance. It is safe to create a few instances and use them in different Threads.
147    *
148    * @param constructor BaseConstructor to construct incoming documents
149    * @param representer Representer to emit outgoing objects
150    * @param dumperOptions DumperOptions to configure outgoing objects
151    * @param loadingConfig LoadingConfig to control load behavior
152    */
Yaml(BaseConstructor constructor, Representer representer, DumperOptions dumperOptions, LoaderOptions loadingConfig)153   public Yaml(BaseConstructor constructor, Representer representer, DumperOptions dumperOptions,
154       LoaderOptions loadingConfig) {
155     this(constructor, representer, dumperOptions, loadingConfig, new Resolver());
156   }
157 
158   /**
159    * Create Yaml instance. It is safe to create a few instances and use them in different Threads.
160    *
161    * @param constructor BaseConstructor to construct incoming documents
162    * @param representer Representer to emit outgoing objects
163    * @param dumperOptions DumperOptions to configure outgoing objects
164    * @param resolver Resolver to detect implicit type
165    */
Yaml(BaseConstructor constructor, Representer representer, DumperOptions dumperOptions, Resolver resolver)166   public Yaml(BaseConstructor constructor, Representer representer, DumperOptions dumperOptions,
167       Resolver resolver) {
168     this(constructor, representer, dumperOptions, new LoaderOptions(), resolver);
169   }
170 
171   /**
172    * Create Yaml instance. It is safe to create a few instances and use them in different Threads.
173    *
174    * @param constructor BaseConstructor to construct incoming documents
175    * @param representer Representer to emit outgoing objects
176    * @param dumperOptions DumperOptions to configure outgoing objects
177    * @param loadingConfig LoadingConfig to control load behavior
178    * @param resolver Resolver to detect implicit type
179    */
Yaml(BaseConstructor constructor, Representer representer, DumperOptions dumperOptions, LoaderOptions loadingConfig, Resolver resolver)180   public Yaml(BaseConstructor constructor, Representer representer, DumperOptions dumperOptions,
181       LoaderOptions loadingConfig, Resolver resolver) {
182     if (!constructor.isExplicitPropertyUtils()) {
183       constructor.setPropertyUtils(representer.getPropertyUtils());
184     } else if (!representer.isExplicitPropertyUtils()) {
185       representer.setPropertyUtils(constructor.getPropertyUtils());
186     }
187     this.constructor = constructor;
188     this.constructor.setAllowDuplicateKeys(loadingConfig.isAllowDuplicateKeys());
189     this.constructor.setWrappedToRootException(loadingConfig.isWrappedToRootException());
190     if (!dumperOptions.getIndentWithIndicator()
191         && dumperOptions.getIndent() <= dumperOptions.getIndicatorIndent()) {
192       throw new YAMLException("Indicator indent must be smaller then indent.");
193     }
194     representer.setDefaultFlowStyle(dumperOptions.getDefaultFlowStyle());
195     representer.setDefaultScalarStyle(dumperOptions.getDefaultScalarStyle());
196     representer.getPropertyUtils()
197         .setAllowReadOnlyProperties(dumperOptions.isAllowReadOnlyProperties());
198     representer.setTimeZone(dumperOptions.getTimeZone());
199     this.representer = representer;
200     this.dumperOptions = dumperOptions;
201     this.loadingConfig = loadingConfig;
202     this.resolver = resolver;
203     this.name = "Yaml:" + System.identityHashCode(this);
204   }
205 
206   /**
207    * Serialize a Java object into a YAML String.
208    *
209    * @param data Java object to be Serialized to YAML
210    * @return YAML String
211    */
dump(Object data)212   public String dump(Object data) {
213     List<Object> list = new ArrayList<Object>(1);
214     list.add(data);
215     return dumpAll(list.iterator());
216   }
217 
218   /**
219    * Produce the corresponding representation tree for a given Object.
220    *
221    * @param data instance to build the representation tree for
222    * @return representation tree
223    * @see <a href="http://yaml.org/spec/1.1/#id859333">Figure 3.1. Processing Overview</a>
224    */
represent(Object data)225   public Node represent(Object data) {
226     return representer.represent(data);
227   }
228 
229   /**
230    * Serialize a sequence of Java objects into a YAML String.
231    *
232    * @param data Iterator with Objects
233    * @return YAML String with all the objects in proper sequence
234    */
dumpAll(Iterator<? extends Object> data)235   public String dumpAll(Iterator<? extends Object> data) {
236     StringWriter buffer = new StringWriter();
237     dumpAll(data, buffer, null);
238     return buffer.toString();
239   }
240 
241   /**
242    * Serialize a Java object into a YAML stream.
243    *
244    * @param data Java object to be serialized to YAML
245    * @param output stream to write to
246    */
dump(Object data, Writer output)247   public void dump(Object data, Writer output) {
248     List<Object> list = new ArrayList<Object>(1);
249     list.add(data);
250     dumpAll(list.iterator(), output, null);
251   }
252 
253   /**
254    * Serialize a sequence of Java objects into a YAML stream.
255    *
256    * @param data Iterator with Objects
257    * @param output stream to write to
258    */
dumpAll(Iterator<? extends Object> data, Writer output)259   public void dumpAll(Iterator<? extends Object> data, Writer output) {
260     dumpAll(data, output, null);
261   }
262 
dumpAll(Iterator<? extends Object> data, Writer output, Tag rootTag)263   private void dumpAll(Iterator<? extends Object> data, Writer output, Tag rootTag) {
264     Serializer serializer =
265         new Serializer(new Emitter(output, dumperOptions), resolver, dumperOptions, rootTag);
266     try {
267       serializer.open();
268       while (data.hasNext()) {
269         Node node = representer.represent(data.next());
270         serializer.serialize(node);
271       }
272       serializer.close();
273     } catch (IOException e) {
274       throw new YAMLException(e);
275     }
276   }
277 
278   /**
279    * <p>
280    * Serialize a Java object into a YAML string. Override the default root tag with
281    * <code>rootTag</code>.
282    * </p>
283    *
284    * <p>
285    * This method is similar to <code>Yaml.dump(data)</code> except that the root tag for the whole
286    * document is replaced with the given tag. This has two main uses.
287    * </p>
288    *
289    * <p>
290    * First, if the root tag is replaced with a standard YAML tag, such as <code>Tag.MAP</code>, then
291    * the object will be dumped as a map. The root tag will appear as <code>!!map</code>, or blank
292    * (implicit !!map).
293    * </p>
294    *
295    * <p>
296    * Second, if the root tag is replaced by a different custom tag, then the document appears to be
297    * a different type when loaded. For example, if an instance of MyClass is dumped with the tag
298    * !!YourClass, then it will be handled as an instance of YourClass when loaded.
299    * </p>
300    *
301    * @param data Java object to be serialized to YAML
302    * @param rootTag the tag for the whole YAML document. The tag should be Tag.MAP for a JavaBean to
303    *        make the tag disappear (to use implicit tag !!map). If <code>null</code> is provided
304    *        then the standard tag with the full class name is used.
305    * @param flowStyle flow style for the whole document. See Chapter 10. Collection Styles
306    *        http://yaml.org/spec/1.1/#id930798. If <code>null</code> is provided then the flow style
307    *        from DumperOptions is used.
308    * @return YAML String
309    */
dumpAs(Object data, Tag rootTag, FlowStyle flowStyle)310   public String dumpAs(Object data, Tag rootTag, FlowStyle flowStyle) {
311     FlowStyle oldStyle = representer.getDefaultFlowStyle();
312     if (flowStyle != null) {
313       representer.setDefaultFlowStyle(flowStyle);
314     }
315     List<Object> list = new ArrayList<Object>(1);
316     list.add(data);
317     StringWriter buffer = new StringWriter();
318     dumpAll(list.iterator(), buffer, rootTag);
319     representer.setDefaultFlowStyle(oldStyle);
320     return buffer.toString();
321   }
322 
323   /**
324    * <p>
325    * Serialize a Java object into a YAML string. Override the default root tag with
326    * <code>Tag.MAP</code>.
327    * </p>
328    * <p>
329    * This method is similar to <code>Yaml.dump(data)</code> except that the root tag for the whole
330    * document is replaced with <code>Tag.MAP</code> tag (implicit !!map).
331    * </p>
332    * <p>
333    * Block Mapping is used as the collection style. See 10.2.2. Block Mappings
334    * (http://yaml.org/spec/1.1/#id934537)
335    * </p>
336    *
337    * @param data Java object to be serialized to YAML
338    * @return YAML String
339    */
dumpAsMap(Object data)340   public String dumpAsMap(Object data) {
341     return dumpAs(data, Tag.MAP, FlowStyle.BLOCK);
342   }
343 
344   /**
345    * Serialize (dump) a YAML node into a YAML stream.
346    *
347    * @param node YAML node to be serialized to YAML
348    * @param output stream to write to
349    */
serialize(Node node, Writer output)350   public void serialize(Node node, Writer output) {
351     Serializer serializer =
352         new Serializer(new Emitter(output, dumperOptions), resolver, dumperOptions, null);
353     try {
354       serializer.open();
355       serializer.serialize(node);
356       serializer.close();
357     } catch (IOException e) {
358       throw new YAMLException(e);
359     }
360   }
361 
362   /**
363    * Serialize the representation tree into Events.
364    *
365    * @param data representation tree
366    * @return Event list
367    * @see <a href="http://yaml.org/spec/1.1/#id859333">Processing Overview</a>
368    */
serialize(Node data)369   public List<Event> serialize(Node data) {
370     SilentEmitter emitter = new SilentEmitter();
371     Serializer serializer = new Serializer(emitter, resolver, dumperOptions, null);
372     try {
373       serializer.open();
374       serializer.serialize(data);
375       serializer.close();
376     } catch (IOException e) {
377       throw new YAMLException(e);
378     }
379     return emitter.getEvents();
380   }
381 
382   private static class SilentEmitter implements Emitable {
383 
384     private final List<Event> events = new ArrayList<Event>(100);
385 
getEvents()386     public List<Event> getEvents() {
387       return events;
388     }
389 
390     @Override
emit(Event event)391     public void emit(Event event) throws IOException {
392       events.add(event);
393     }
394   }
395 
396   /**
397    * Parse the only YAML document in a String and produce the corresponding Java object. (Because
398    * the encoding in known BOM is not respected.)
399    *
400    * @param yaml YAML data to load from (BOM must not be present)
401    * @param <T> the class of the instance to be created
402    * @return parsed object
403    */
404   @SuppressWarnings("unchecked")
load(String yaml)405   public <T> T load(String yaml) {
406     return (T) loadFromReader(new StreamReader(yaml), Object.class);
407   }
408 
409   /**
410    * Parse the only YAML document in a stream and produce the corresponding Java object.
411    *
412    * @param io data to load from (BOM is respected to detect encoding and removed from the data)
413    * @param <T> the class of the instance to be created
414    * @return parsed object
415    */
416   @SuppressWarnings("unchecked")
load(InputStream io)417   public <T> T load(InputStream io) {
418     return (T) loadFromReader(new StreamReader(new UnicodeReader(io)), Object.class);
419   }
420 
421   /**
422    * Parse the only YAML document in a stream and produce the corresponding Java object.
423    *
424    * @param io data to load from (BOM must not be present)
425    * @param <T> the class of the instance to be created
426    * @return parsed object
427    */
428   @SuppressWarnings("unchecked")
load(Reader io)429   public <T> T load(Reader io) {
430     return (T) loadFromReader(new StreamReader(io), Object.class);
431   }
432 
433   /**
434    * Parse the only YAML document in a stream and produce the corresponding Java object.
435    *
436    * @param <T> Class is defined by the second argument
437    * @param io data to load from (BOM must not be present)
438    * @param type Class of the object to be created
439    * @return parsed object
440    */
441   @SuppressWarnings("unchecked")
loadAs(Reader io, Class<T> type)442   public <T> T loadAs(Reader io, Class<T> type) {
443     return (T) loadFromReader(new StreamReader(io), type);
444   }
445 
446   /**
447    * Parse the only YAML document in a String and produce the corresponding Java object. (Because
448    * the encoding in known BOM is not respected.)
449    *
450    * @param <T> Class is defined by the second argument
451    * @param yaml YAML data to load from (BOM must not be present)
452    * @param type Class of the object to be created
453    * @return parsed object
454    */
455   @SuppressWarnings("unchecked")
loadAs(String yaml, Class<T> type)456   public <T> T loadAs(String yaml, Class<T> type) {
457     return (T) loadFromReader(new StreamReader(yaml), type);
458   }
459 
460   /**
461    * Parse the only YAML document in a stream and produce the corresponding Java object.
462    *
463    * @param <T> Class is defined by the second argument
464    * @param input data to load from (BOM is respected to detect encoding and removed from the data)
465    * @param type Class of the object to be created
466    * @return parsed object
467    */
468   @SuppressWarnings("unchecked")
loadAs(InputStream input, Class<T> type)469   public <T> T loadAs(InputStream input, Class<T> type) {
470     return (T) loadFromReader(new StreamReader(new UnicodeReader(input)), type);
471   }
472 
loadFromReader(StreamReader sreader, Class<?> type)473   private Object loadFromReader(StreamReader sreader, Class<?> type) {
474     Composer composer =
475         new Composer(new ParserImpl(sreader, loadingConfig), resolver, loadingConfig);
476     constructor.setComposer(composer);
477     return constructor.getSingleData(type);
478   }
479 
480   /**
481    * Parse all YAML documents in the Reader and produce corresponding Java objects. The documents
482    * are parsed only when the iterator is invoked.
483    *
484    * @param yaml YAML data to load from (BOM must not be present)
485    * @return an Iterable over the parsed Java objects in this String in proper sequence
486    */
loadAll(Reader yaml)487   public Iterable<Object> loadAll(Reader yaml) {
488     Composer composer =
489         new Composer(new ParserImpl(new StreamReader(yaml), loadingConfig.isProcessComments()),
490             resolver, loadingConfig);
491     constructor.setComposer(composer);
492     Iterator<Object> result = new Iterator<Object>() {
493       @Override
494       public boolean hasNext() {
495         return constructor.checkData();
496       }
497 
498       @Override
499       public Object next() {
500         return constructor.getData();
501       }
502 
503       @Override
504       public void remove() {
505         throw new UnsupportedOperationException();
506       }
507     };
508     return new YamlIterable(result);
509   }
510 
511   private static class YamlIterable implements Iterable<Object> {
512 
513     private final Iterator<Object> iterator;
514 
YamlIterable(Iterator<Object> iterator)515     public YamlIterable(Iterator<Object> iterator) {
516       this.iterator = iterator;
517     }
518 
519     @Override
iterator()520     public Iterator<Object> iterator() {
521       return iterator;
522     }
523   }
524 
525   /**
526    * Parse all YAML documents in a String and produce corresponding Java objects. (Because the
527    * encoding in known BOM is not respected.) The documents are parsed only when the iterator is
528    * invoked.
529    *
530    * @param yaml YAML data to load from (BOM must not be present)
531    * @return an Iterable over the parsed Java objects in this String in proper sequence
532    */
loadAll(String yaml)533   public Iterable<Object> loadAll(String yaml) {
534     return loadAll(new StringReader(yaml));
535   }
536 
537   /**
538    * Parse all YAML documents in a stream and produce corresponding Java objects. The documents are
539    * parsed only when the iterator is invoked.
540    *
541    * @param yaml YAML data to load from (BOM is respected to detect encoding and removed from the
542    *        data)
543    * @return an Iterable over the parsed Java objects in this stream in proper sequence
544    */
loadAll(InputStream yaml)545   public Iterable<Object> loadAll(InputStream yaml) {
546     return loadAll(new UnicodeReader(yaml));
547   }
548 
549   /**
550    * Parse the first YAML document in a stream and produce the corresponding representation tree.
551    * (This is the opposite of the represent() method)
552    *
553    * @param yaml YAML document
554    * @return parsed root Node for the specified YAML document
555    * @see <a href="http://yaml.org/spec/1.1/#id859333">Figure 3.1. Processing Overview</a>
556    */
compose(Reader yaml)557   public Node compose(Reader yaml) {
558     Composer composer =
559         new Composer(new ParserImpl(new StreamReader(yaml), loadingConfig.isProcessComments()),
560             resolver, loadingConfig);
561     return composer.getSingleNode();
562   }
563 
564   /**
565    * Parse all YAML documents in a stream and produce corresponding representation trees.
566    *
567    * @param yaml stream of YAML documents
568    * @return parsed root Nodes for all the specified YAML documents
569    * @see <a href="http://yaml.org/spec/1.1/#id859333">Processing Overview</a>
570    */
composeAll(Reader yaml)571   public Iterable<Node> composeAll(Reader yaml) {
572     final Composer composer =
573         new Composer(new ParserImpl(new StreamReader(yaml), loadingConfig.isProcessComments()),
574             resolver, loadingConfig);
575     Iterator<Node> result = new Iterator<Node>() {
576       @Override
577       public boolean hasNext() {
578         return composer.checkNode();
579       }
580 
581       @Override
582       public Node next() {
583         Node node = composer.getNode();
584         if (node != null) {
585           return node;
586         } else {
587           throw new NoSuchElementException("No Node is available.");
588         }
589       }
590 
591       @Override
592       public void remove() {
593         throw new UnsupportedOperationException();
594       }
595     };
596     return new NodeIterable(result);
597   }
598 
599   private static class NodeIterable implements Iterable<Node> {
600 
601     private final Iterator<Node> iterator;
602 
NodeIterable(Iterator<Node> iterator)603     public NodeIterable(Iterator<Node> iterator) {
604       this.iterator = iterator;
605     }
606 
607     @Override
iterator()608     public Iterator<Node> iterator() {
609       return iterator;
610     }
611   }
612 
613   /**
614    * Add an implicit scalar detector. If an implicit scalar value matches the given regexp, the
615    * corresponding tag is assigned to the scalar.
616    *
617    * @param tag tag to assign to the node
618    * @param regexp regular expression to match against
619    * @param first a sequence of possible initial characters or null (which means any).
620    */
addImplicitResolver(Tag tag, Pattern regexp, String first)621   public void addImplicitResolver(Tag tag, Pattern regexp, String first) {
622     resolver.addImplicitResolver(tag, regexp, first);
623   }
624 
625   /**
626    * Add an implicit scalar detector. If an implicit scalar value matches the given regexp, the
627    * corresponding tag is assigned to the scalar.
628    *
629    * @param tag tag to assign to the node
630    * @param regexp regular expression to match against
631    * @param first a sequence of possible initial characters or null (which means any).
632    * @param limit the max length of the value which may match the regular expression
633    */
addImplicitResolver(Tag tag, Pattern regexp, String first, int limit)634   public void addImplicitResolver(Tag tag, Pattern regexp, String first, int limit) {
635     resolver.addImplicitResolver(tag, regexp, first, limit);
636   }
637 
638   @Override
toString()639   public String toString() {
640     return name;
641   }
642 
643   /**
644    * Get a meaningful name. It simplifies debugging in a multi-threaded environment. If nothing is
645    * set explicitly the address of the instance is returned.
646    *
647    * @return human readable name
648    */
getName()649   public String getName() {
650     return name;
651   }
652 
653   /**
654    * Set a meaningful name to be shown in toString()
655    *
656    * @param name human readable name
657    */
setName(String name)658   public void setName(String name) {
659     this.name = name;
660   }
661 
662   /**
663    * Parse a YAML stream and produce parsing events.
664    *
665    * @param yaml YAML document(s)
666    * @return parsed events
667    * @see <a href="http://yaml.org/spec/1.1/#id859333">Processing Overview</a>
668    */
parse(Reader yaml)669   public Iterable<Event> parse(Reader yaml) {
670     final Parser parser = new ParserImpl(new StreamReader(yaml), loadingConfig.isProcessComments());
671     Iterator<Event> result = new Iterator<Event>() {
672       @Override
673       public boolean hasNext() {
674         return parser.peekEvent() != null;
675       }
676 
677       @Override
678       public Event next() {
679         Event event = parser.getEvent();
680         if (event != null) {
681           return event;
682         } else {
683           throw new NoSuchElementException("No Event is available.");
684         }
685       }
686 
687       @Override
688       public void remove() {
689         throw new UnsupportedOperationException();
690       }
691     };
692     return new EventIterable(result);
693   }
694 
695   private static class EventIterable implements Iterable<Event> {
696 
697     private final Iterator<Event> iterator;
698 
EventIterable(Iterator<Event> iterator)699     public EventIterable(Iterator<Event> iterator) {
700       this.iterator = iterator;
701     }
702 
703     @Override
iterator()704     public Iterator<Event> iterator() {
705       return iterator;
706     }
707   }
708 
setBeanAccess(BeanAccess beanAccess)709   public void setBeanAccess(BeanAccess beanAccess) {
710     constructor.getPropertyUtils().setBeanAccess(beanAccess);
711     representer.getPropertyUtils().setBeanAccess(beanAccess);
712   }
713 
addTypeDescription(TypeDescription td)714   public void addTypeDescription(TypeDescription td) {
715     constructor.addTypeDescription(td);
716     representer.addTypeDescription(td);
717   }
718 }
719