View Javadoc

1   /**
2    * Copyright (c) 2008-2011, http://www.snakeyaml.org
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.yaml.snakeyaml.recursive.generics;
18  
19  import java.beans.IntrospectionException;
20  import java.io.IOException;
21  import java.util.ArrayList;
22  import java.util.Date;
23  import java.util.HashMap;
24  import java.util.LinkedHashMap;
25  import java.util.LinkedHashSet;
26  import java.util.List;
27  import java.util.Map;
28  import java.util.Map.Entry;
29  import java.util.Set;
30  
31  import junit.framework.TestCase;
32  
33  import org.yaml.snakeyaml.TypeDescription;
34  import org.yaml.snakeyaml.Util;
35  import org.yaml.snakeyaml.Yaml;
36  import org.yaml.snakeyaml.constructor.Constructor;
37  import org.yaml.snakeyaml.generics.GenericsBugDetector;
38  import org.yaml.snakeyaml.nodes.Tag;
39  import org.yaml.snakeyaml.representer.Representer;
40  
41  public class HumanGenericsTest extends TestCase {
42  
43      public void testNoChildren() throws IOException, IntrospectionException {
44          if (!GenericsBugDetector.isProperIntrospection()) {
45              return;
46          }
47          HumanGen father = new HumanGen();
48          father.setName("Father");
49          father.setBirthday(new Date(1000000000));
50          father.setBirthPlace("Leningrad");
51          father.setBankAccountOwner(father);
52          HumanGen mother = new HumanGen();
53          mother.setName("Mother");
54          mother.setBirthday(new Date(100000000000L));
55          mother.setBirthPlace("Saint-Petersburg");
56          father.setPartner(mother);
57          mother.setPartner(father);
58          mother.setBankAccountOwner(father);
59          Yaml yaml = new Yaml();
60          String output = yaml.dump(father);
61          String etalon = Util.getLocalResource("recursive/generics/no-children-1.yaml");
62          assertEquals(etalon, output);
63          //
64          HumanGen father2 = (HumanGen) yaml.load(output);
65          assertNotNull(father2);
66          assertEquals("Father", father2.getName());
67          assertEquals("Mother", father2.getPartner().getName());
68          assertEquals("Father", father2.getBankAccountOwner().getName());
69          assertSame(father2, father2.getBankAccountOwner());
70      }
71  
72      /**
73       * the YAML document should contain no global tags
74       * 
75       * @throws IntrospectionException
76       */
77      public void testNoChildren2() throws IOException, IntrospectionException {
78          if (!GenericsBugDetector.isProperIntrospection()) {
79              return;
80          }
81          HumanGen father = new HumanGen();
82          father.setName("Father");
83          father.setBirthday(new Date(1000000000));
84          father.setBirthPlace("Leningrad");
85          father.setBankAccountOwner(father);
86          HumanGen mother = new HumanGen();
87          mother.setName("Mother");
88          mother.setBirthday(new Date(100000000000L));
89          mother.setBirthPlace("Saint-Petersburg");
90          father.setPartner(mother);
91          mother.setPartner(father);
92          mother.setBankAccountOwner(father);
93          Yaml yaml = new Yaml();
94          String output = yaml.dumpAsMap(father);
95          String etalon = Util.getLocalResource("recursive/generics/no-children-2.yaml");
96          assertEquals(etalon, output);
97          //
98          Yaml loader = new Yaml();
99          HumanGen father2 = (HumanGen) loader.loadAs(etalon, HumanGen.class);
100         assertNotNull(father2);
101         assertEquals("Father", father2.getName());
102         assertEquals("Mother", father2.getPartner().getName());
103         assertEquals("Father", father2.getBankAccountOwner().getName());
104         assertSame(father2, father2.getBankAccountOwner());
105     }
106 
107     public void testChildren() throws IOException, IntrospectionException {
108         if (!GenericsBugDetector.isProperIntrospection()) {
109             return;
110         }
111         HumanGen father = new HumanGen();
112         father.setName("Father");
113         father.setBirthday(new Date(1000000000));
114         father.setBirthPlace("Leningrad");
115         father.setBankAccountOwner(father);
116         //
117         HumanGen mother = new HumanGen();
118         mother.setName("Mother");
119         mother.setBirthday(new Date(100000000000L));
120         mother.setBirthPlace("Saint-Petersburg");
121         father.setPartner(mother);
122         mother.setPartner(father);
123         mother.setBankAccountOwner(father);
124         //
125         HumanGen son = new HumanGen();
126         son.setName("Son");
127         son.setBirthday(new Date(310000000000L));
128         son.setBirthPlace("Munich");
129         son.setBankAccountOwner(father);
130         son.setFather(father);
131         son.setMother(mother);
132         //
133         HumanGen daughter = new HumanGen();
134         daughter.setName("Daughter");
135         daughter.setBirthday(new Date(420000000000L));
136         daughter.setBirthPlace("New York");
137         daughter.setBankAccountOwner(father);
138         daughter.setFather(father);
139         daughter.setMother(mother);
140         //
141         Set<HumanGen> children = new LinkedHashSet<HumanGen>(2);
142         children.add(son);
143         children.add(daughter);
144         father.setChildren(children);
145         mother.setChildren(children);
146         //
147 
148         Constructor constructor = new Constructor();
149         TypeDescription humanDescription = new TypeDescription(HumanGen.class);
150         humanDescription.putMapPropertyType("children", HumanGen.class, Object.class);
151         constructor.addTypeDescription(humanDescription);
152 
153         Yaml yaml = new Yaml(constructor);
154         String output = yaml.dump(son);
155         // System.out.println(output);
156         String etalon = Util.getLocalResource("recursive/generics/with-children.yaml");
157         assertEquals(etalon, output);
158         //
159         HumanGen son2 = (HumanGen) yaml.load(output);
160         assertNotNull(son2);
161         assertEquals("Son", son.getName());
162 
163         HumanGen father2 = son2.getFather();
164         assertEquals("Father", father2.getName());
165         assertEquals("Mother", son2.getMother().getName());
166         assertSame(father2, father2.getBankAccountOwner());
167         assertSame(father2.getPartner(), son2.getMother());
168         assertSame(father2, son2.getMother().getPartner());
169 
170         Set<HumanGen> children2 = father2.getChildren();
171         assertEquals(2, children2.size());
172         assertSame(father2.getPartner().getChildren(), children2);
173 
174         for (Object child : children2) {
175             assertSame(HumanGen.class, child.getClass()); // check if type
176             // descriptor was correct
177         }
178     }
179 
180     public void testChildren2() throws IOException, IntrospectionException {
181         if (!GenericsBugDetector.isProperIntrospection()) {
182             return;
183         }
184         HumanGen2 father = new HumanGen2();
185         father.setName("Father");
186         father.setBirthday(new Date(1000000000));
187         father.setBirthPlace("Leningrad");
188         father.setBankAccountOwner(father);
189         //
190         HumanGen2 mother = new HumanGen2();
191         mother.setName("Mother");
192         mother.setBirthday(new Date(100000000000L));
193         mother.setBirthPlace("Saint-Petersburg");
194         father.setPartner(mother);
195         mother.setPartner(father);
196         mother.setBankAccountOwner(father);
197         //
198         HumanGen2 son = new HumanGen2();
199         son.setName("Son");
200         son.setBirthday(new Date(310000000000L));
201         son.setBirthPlace("Munich");
202         son.setBankAccountOwner(father);
203         son.setFather(father);
204         son.setMother(mother);
205         //
206         HumanGen2 daughter = new HumanGen2();
207         daughter.setName("Daughter");
208         daughter.setBirthday(new Date(420000000000L));
209         daughter.setBirthPlace("New York");
210         daughter.setBankAccountOwner(father);
211         daughter.setFather(father);
212         daughter.setMother(mother);
213         //
214         HashMap<HumanGen2, String> children = new LinkedHashMap<HumanGen2, String>(2);
215         children.put(son, "son");
216         children.put(daughter, "daughter");
217         father.setChildren(children);
218         mother.setChildren(children);
219         //
220         Representer representer = new Representer();
221         representer.addClassTag(HumanGen2.class, Tag.MAP);
222         Yaml yaml = new Yaml(representer);
223         String output = yaml.dump(son);
224         // System.out.println(output);
225         String etalon = Util.getLocalResource("recursive/generics/with-children-2.yaml");
226         assertEquals(etalon, output);
227         // load
228         TypeDescription humanDescription = new TypeDescription(HumanGen2.class);
229         humanDescription.putMapPropertyType("children", HumanGen2.class, String.class);
230         Yaml beanLoader = new Yaml(new Constructor(humanDescription));
231         //
232         HumanGen2 son2 = beanLoader.loadAs(output, HumanGen2.class);
233         assertNotNull(son2);
234         assertEquals("Son", son.getName());
235 
236         HumanGen2 father2 = son2.getFather();
237         assertEquals("Father", father2.getName());
238         assertEquals("Mother", son2.getMother().getName());
239         assertSame(father2, father2.getBankAccountOwner());
240         assertSame(father2.getPartner(), son2.getMother());
241         assertSame(father2, son2.getMother().getPartner());
242 
243         Map<HumanGen2, String> children2 = father2.getChildren();
244         assertEquals(2, children2.size());
245         assertSame(father2.getPartner().getChildren(), children2);
246 
247     }
248 
249     public void testChildren3() throws IOException, IntrospectionException {
250         if (!GenericsBugDetector.isProperIntrospection()) {
251             return;
252         }
253         HumanGen3 father = new HumanGen3();
254         father.setName("Father");
255         father.setBirthday(new Date(1000000000));
256         father.setBirthPlace("Leningrad");
257         father.setBankAccountOwner(father);
258         //
259         HumanGen3 mother = new HumanGen3();
260         mother.setName("Mother");
261         mother.setBirthday(new Date(100000000000L));
262         mother.setBirthPlace("Saint-Petersburg");
263         father.setPartner(mother);
264         mother.setPartner(father);
265         mother.setBankAccountOwner(father);
266         //
267         HumanGen3 son = new HumanGen3();
268         son.setName("Son");
269         son.setBirthday(new Date(310000000000L));
270         son.setBirthPlace("Munich");
271         son.setBankAccountOwner(father);
272         son.setFather(father);
273         son.setMother(mother);
274         //
275         HumanGen3 daughter = new HumanGen3();
276         daughter.setName("Daughter");
277         daughter.setBirthday(new Date(420000000000L));
278         daughter.setBirthPlace("New York");
279         daughter.setBankAccountOwner(father);
280         daughter.setFather(father);
281         daughter.setMother(mother);
282         //
283         ArrayList<HumanGen3> children = new ArrayList<HumanGen3>();
284         children.add(son);
285         children.add(daughter);
286         father.setChildren(children);
287         mother.setChildren(children);
288         //
289 
290         Constructor constructor = new Constructor();
291         TypeDescription Human3Description = new TypeDescription(HumanGen3.class);
292         Human3Description.putListPropertyType("children", HumanGen3.class);
293         constructor.addTypeDescription(Human3Description);
294 
295         Yaml yaml = new Yaml(constructor);
296         String output = yaml.dump(son);
297         // System.out.println(output);
298         String etalon = Util.getLocalResource("recursive/generics/with-children-3.yaml");
299         assertEquals(etalon, output);
300         //
301         HumanGen3 son2 = (HumanGen3) yaml.load(output);
302         assertNotNull(son2);
303         assertEquals("Son", son.getName());
304 
305         HumanGen3 father2 = son2.getFather();
306         assertEquals("Father", father2.getName());
307         assertEquals("Mother", son2.getMother().getName());
308         assertSame(father2, father2.getBankAccountOwner());
309         assertSame(father2.getPartner(), son2.getMother());
310         assertSame(father2, son2.getMother().getPartner());
311 
312         List<HumanGen3> children2 = father2.getChildren();
313         assertEquals(2, children2.size());
314         assertSame(father2.getPartner().getChildren(), children2);
315 
316         for (Object child : children2) {
317             assertSame(HumanGen3.class, child.getClass()); // check if type
318             // descriptor was
319             // correct
320         }
321     }
322 
323     /*
324      * Loads same structure as created in testChildren. But root object is set
325      * of children
326      */
327     @SuppressWarnings("unchecked")
328     public void testChildrenSetAsRoot() throws IOException, IntrospectionException {
329         if (!GenericsBugDetector.isProperIntrospection()) {
330             return;
331         }
332         String etalon = Util.getLocalResource("recursive/generics/with-children-as-set.yaml");
333 
334         Constructor constructor = new Constructor();
335         TypeDescription humanDescription = new TypeDescription(HumanGen.class);
336         humanDescription.putMapPropertyType("children", HumanGen.class, Object.class);
337         constructor.addTypeDescription(humanDescription);
338 
339         Yaml yaml = new Yaml(constructor);
340         Set<HumanGen> children2 = (Set<HumanGen>) yaml.load(etalon);
341         assertNotNull(children2);
342         assertEquals(2, children2.size());
343 
344         HumanGen firstChild = children2.iterator().next();
345 
346         HumanGen father2 = firstChild.getFather();
347         assertEquals("Father", father2.getName());
348         assertEquals("Mother", firstChild.getMother().getName());
349         assertSame(father2, father2.getBankAccountOwner());
350         assertSame(father2.getPartner(), firstChild.getMother());
351         assertSame(father2, firstChild.getMother().getPartner());
352 
353         assertSame(father2.getPartner().getChildren(), children2);
354 
355         for (Object child : children2) {
356             assertSame(HumanGen.class, child.getClass()); // check if type
357             // descriptor was correct
358         }
359     }
360 
361     /*
362      * Loads same structure as created in testChildren. But root object is map
363      * of children
364      */
365     @SuppressWarnings("unchecked")
366     public void testChildrenMapAsRoot() throws IOException, IntrospectionException {
367         if (!GenericsBugDetector.isProperIntrospection()) {
368             return;
369         }
370         String etalon = Util.getLocalResource("recursive/generics/with-children-as-map.yaml");
371 
372         Constructor constructor = new Constructor();
373         TypeDescription Human2Description = new TypeDescription(HumanGen2.class);
374         Human2Description.putMapPropertyType("children", HumanGen2.class, String.class);
375         constructor.addTypeDescription(Human2Description);
376 
377         Yaml yaml = new Yaml(constructor);
378         Map<HumanGen2, String> children2 = (Map<HumanGen2, String>) yaml.load(etalon);
379         assertNotNull(children2);
380         assertEquals(2, children2.size());
381 
382         Entry<HumanGen2, String> firstEntry = children2.entrySet().iterator().next();
383         HumanGen2 firstChild = firstEntry.getKey();
384 
385         HumanGen2 father2 = firstChild.getFather();
386         assertEquals("Father", father2.getName());
387         assertEquals("Mother", firstChild.getMother().getName());
388         assertSame(father2, father2.getBankAccountOwner());
389         assertSame(father2.getPartner(), firstChild.getMother());
390         assertSame(father2, firstChild.getMother().getPartner());
391 
392         assertSame(father2.getPartner().getChildren(), children2);
393     }
394 
395     /*
396      * Loads same structure as created in testChildren. But root object is list
397      * of children
398      */
399     @SuppressWarnings("unchecked")
400     public void testChildrenListRoot() throws IOException, IntrospectionException {
401         if (!GenericsBugDetector.isProperIntrospection()) {
402             return;
403         }
404         HumanGen3 father = new HumanGen3();
405         father.setName("Father");
406         father.setBirthday(new Date(1000000000));
407         father.setBirthPlace("Leningrad");
408         father.setBankAccountOwner(father);
409         //
410         HumanGen3 mother = new HumanGen3();
411         mother.setName("Mother");
412         mother.setBirthday(new Date(100000000000L));
413         mother.setBirthPlace("Saint-Petersburg");
414         father.setPartner(mother);
415         mother.setPartner(father);
416         mother.setBankAccountOwner(father);
417         //
418         HumanGen3 son = new HumanGen3();
419         son.setName("Son");
420         son.setBirthday(new Date(310000000000L));
421         son.setBirthPlace("Munich");
422         son.setBankAccountOwner(father);
423         son.setFather(father);
424         son.setMother(mother);
425         //
426         HumanGen3 daughter = new HumanGen3();
427         daughter.setName("Daughter");
428         daughter.setBirthday(new Date(420000000000L));
429         daughter.setBirthPlace("New York");
430         daughter.setBankAccountOwner(father);
431         daughter.setFather(father);
432         daughter.setMother(mother);
433         //
434         ArrayList<HumanGen3> children = new ArrayList<HumanGen3>();
435         children.add(son);
436         children.add(daughter);
437         father.setChildren(children);
438         mother.setChildren(children);
439         //
440 
441         Constructor constructor = new Constructor();
442         TypeDescription Human3Description = new TypeDescription(HumanGen3.class);
443         Human3Description.putListPropertyType("children", HumanGen3.class);
444         constructor.addTypeDescription(Human3Description);
445 
446         Yaml yaml = new Yaml(constructor);
447         String output = yaml.dump(father.getChildren());
448         // System.out.println(output);
449         String etalon = Util.getLocalResource("recursive/generics/with-children-as-list.yaml");
450         assertEquals(etalon, output);
451         //
452         List<HumanGen3> children2 = (List<HumanGen3>) yaml.load(output);
453         assertNotNull(children2);
454         HumanGen3 son2 = children2.iterator().next();
455         assertEquals(2, children2.size());
456 
457         HumanGen3 father2 = son2.getFather();
458         assertEquals("Father", father2.getName());
459         assertEquals("Mother", son2.getMother().getName());
460         assertSame(father2, father2.getBankAccountOwner());
461         assertSame(father2.getPartner(), son2.getMother());
462         assertSame(father2, son2.getMother().getPartner());
463 
464         assertSame(father2.getPartner().getChildren(), children2);
465 
466         for (Object child : children2) {
467             assertSame(HumanGen3.class, child.getClass()); // check if type
468             // descriptor was
469             // correct
470         }
471     }
472 
473     public void testBeanRing() throws IOException, IntrospectionException {
474         if (!GenericsBugDetector.isProperIntrospection()) {
475             return;
476         }
477         HumanGen man1 = new HumanGen();
478         man1.setName("Man 1");
479         HumanGen man2 = new HumanGen();
480         man2.setName("Man 2");
481         HumanGen man3 = new HumanGen();
482         man3.setName("Man 3");
483         man1.setBankAccountOwner(man2);
484         man2.setBankAccountOwner(man3);
485         man3.setBankAccountOwner(man1);
486         //
487         Yaml yaml = new Yaml();
488         String output = yaml.dump(man1);
489         // System.out.println(output);
490         String etalon = Util.getLocalResource("recursive/generics/beanring-3.yaml");
491         assertEquals(etalon, output);
492         //
493         HumanGen loadedMan1 = (HumanGen) yaml.load(output);
494         assertNotNull(loadedMan1);
495         assertEquals("Man 1", loadedMan1.getName());
496         HumanGen loadedMan2 = loadedMan1.getBankAccountOwner();
497         HumanGen loadedMan3 = loadedMan2.getBankAccountOwner();
498         assertSame(loadedMan1, loadedMan3.getBankAccountOwner());
499     }
500 }