View Javadoc

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