1   /*
2    * Copyright 2001-2004 The Apache Software Foundation.
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.apache.commons.betwixt.io.read;
17  
18  import java.io.StringReader;
19  import java.io.StringWriter;
20  import java.util.ArrayList;
21  
22  import junit.framework.Test;
23  import junit.framework.TestSuite;
24  
25  import org.apache.commons.betwixt.AbstractTestCase;
26  import org.apache.commons.betwixt.io.BeanReader;
27  import org.apache.commons.betwixt.io.BeanWriter;
28  
29  /*** 
30   * Test harness for bean creation (during reading).
31   * 
32   * @author Robert Burrell Donkin
33   * @version $Id: TestBeanCreation.java,v 1.5 2004/02/28 13:38:36 yoavs Exp $
34   */
35  public class TestBeanCreation extends AbstractTestCase {
36  
37      public TestBeanCreation(String name) {
38          super(name);
39      }
40          
41      public static Test suite() {
42          return new TestSuite(TestBeanCreation.class);
43      }    
44      
45      public void testCustomCreatorOne() throws Exception {
46          HouseBeans houses = new HouseBeans();
47          HouseBean houseOne = new HouseBean();
48          houseOne.setFacing(CompassPoint.NORTH);
49          houseOne.setAddress(new AddressBean("Black Bull, 46 Briggate", "Brighouse", "England", "HD6 1EF"));
50          houseOne.setHouseholder(new PersonBean("Samual", "Smith"));
51          houseOne.setTenant(false);
52          houses.addHouse(houseOne);
53          HouseBean houseTwo = new HouseBean();
54          houseTwo.setFacing(CompassPoint.SOUTH);
55          houseTwo.setAddress(new AddressBean("The Commerical Inn, 1 Gooder Lane", "Brighouse", "England", "HD6 1HT"));
56          houseTwo.setHouseholder(new PersonBean("Timothy", "Tayler"));
57          houseTwo.setTenant(true);
58          houses.addHouse(houseTwo);
59          
60          StringWriter out = new StringWriter();
61          out.write("<?xml version='1.0'?>");
62          BeanWriter writer = new BeanWriter(out);
63          writer.getXMLIntrospector().setAttributesForPrimitives(true);
64          writer.getXMLIntrospector().setWrapCollectionsInElement(false);
65          writer.write("houses", houses);
66          
67          String xml = "<?xml version='1.0'?><houses>"
68              + "<house tenant='false'>"
69              + "<address street='Black Bull, 46 Briggate' city='Brighouse' country='England' code='HD6 1EF'/>"
70              + "<householder forename='Samual' surname='Smith'/>"
71              + "<facing name='North'/>"
72              + "</house>"
73              + "<house tenant='true'>"
74              + "<address street='The Commerical Inn, 1 Gooder Lane' city='Brighouse'" 
75              + " country='England' code='HD6 1HT'/>"
76              + "<householder forename='Timothy' surname='Tayler'/>"
77              + "<facing name='South'/>"
78              + "</house>"
79              + "</houses>";
80          
81          xmlAssertIsomorphic(parseString(xml), parseString(out.toString()), true);
82  
83          BeanCreationList chain = BeanCreationList.createStandardChain();
84          // add a filter that creates enums to the start
85          
86          class EnumCreator implements ChainedBeanCreator {
87              
88              public Object create(ElementMapping mapping, ReadContext context, BeanCreationChain chain) {
89                  if ("facing".equals(mapping.getName())) {
90                      String value = mapping.getAttributes().getValue("name");
91                      if ("North".equals(value)) {
92                          return CompassPoint.NORTH;
93                      }
94                      if ("South".equals(value)) {
95                          return CompassPoint.SOUTH;
96                      }
97                      if ("East".equals(value)) {
98                          return CompassPoint.EAST;
99                      }
100                     if ("West".equals(value)) {
101                         return CompassPoint.WEST;
102                     }
103                 }
104                 return chain.create(mapping, context);
105             }
106         }
107         chain.insertBeanCreator(1, new EnumCreator());
108         
109         BeanReader reader = new BeanReader();
110         reader.getXMLIntrospector().setAttributesForPrimitives(true);
111         reader.getXMLIntrospector().setWrapCollectionsInElement(false);
112         reader.registerBeanClass("houses", HouseBeans.class);
113         reader.getReadConfiguration().setBeanCreationChain(chain);
114         
115         StringReader in = new StringReader(xml);
116         HouseBeans newHouses = (HouseBeans) reader.parse(in);
117         assertNotNull("Parsing should return a bean", newHouses);
118         
119         ArrayList houseList = newHouses.houses;
120         assertEquals("Should be two houses read", 2, houseList.size());
121         HouseBean newOne = (HouseBean) houseList.get(0);
122         HouseBean newTwo = (HouseBean) houseList.get(1);
123         assertEquals("First house is equal",  houseOne, newOne);
124         assertEquals("Second house is equal",  houseTwo, newTwo);
125         
126     }
127     
128     public void testCustomCreatorTwo() throws Exception {
129         HouseBeans houses = new HouseBeans();
130         HouseBean houseOne = new HouseBean();
131         houseOne.setFacing(CompassPoint.NORTH);
132         houseOne.setAddress(new AddressBean("Black Bull, 46 Briggate", "Brighouse", "England", "HD6 1EF"));
133         houseOne.setHouseholder(new PersonBean("Samual", "Smith"));
134         houseOne.setTenant(false);
135         houses.addHouse(houseOne);
136         HouseBean houseTwo = new HouseBean();
137         houseTwo.setFacing(CompassPoint.SOUTH);
138         houseTwo.setAddress(new AddressBean("The Commerical Inn, 1 Gooder Lane", "Brighouse", "England", "HD6 1HT"));
139         houseTwo.setHouseholder(new PersonBean("Timothy", "Tayler"));
140         houseTwo.setTenant(true);
141         houses.addHouse(houseTwo);
142         
143         StringWriter out = new StringWriter();
144         out.write("<?xml version='1.0'?>");
145         BeanWriter writer = new BeanWriter(out);
146         writer.getXMLIntrospector().setAttributesForPrimitives(true);
147         writer.getXMLIntrospector().setWrapCollectionsInElement(false);
148         writer.write("houses", houses);
149         
150         String xml = "<?xml version='1.0'?><houses>"
151             + "<house tenant='false'>"
152             + "<address street='Black Bull, 46 Briggate' city='Brighouse' country='England' code='HD6 1EF'/>"
153             + "<householder forename='Samual' surname='Smith'/>"
154             + "<facing name='North'/>"
155             + "</house>"
156             + "<house tenant='true'>"
157             + "<address street='The Commerical Inn, 1 Gooder Lane' city='Brighouse'" 
158             + " country='England' code='HD6 1HT'/>"
159             + "<householder forename='Timothy' surname='Tayler'/>"
160             + "<facing name='South'/>"
161             + "</house>"
162             + "</houses>";
163         
164         xmlAssertIsomorphic(parseString(xml), parseString(out.toString()), true);
165 
166         BeanCreationList chain = BeanCreationList.createStandardChain();
167         // add a filter that creates enums to the start
168         
169         class EnumCreator implements ChainedBeanCreator {
170             // match by class this time
171             public Object create(ElementMapping mapping, ReadContext context, BeanCreationChain chain) {
172                 if (CompassPoint.class.equals(mapping.getType())) {
173                     String value = mapping.getAttributes().getValue("name");
174                     if ("North".equals(value)) {
175                         return CompassPoint.NORTH;
176                     }
177                     if ("South".equals(value)) {
178                         return CompassPoint.SOUTH;
179                     }
180                     if ("East".equals(value)) {
181                         return CompassPoint.EAST;
182                     }
183                     if ("West".equals(value)) {
184                         return CompassPoint.WEST;
185                     }
186                 }
187                 return chain.create(mapping, context);
188             }
189         }
190         chain.insertBeanCreator(1, new EnumCreator());
191         
192         BeanReader reader = new BeanReader();
193         reader.getXMLIntrospector().setAttributesForPrimitives(true);
194         reader.getXMLIntrospector().setWrapCollectionsInElement(false);
195         reader.registerBeanClass("houses", HouseBeans.class);
196         reader.getReadConfiguration().setBeanCreationChain(chain);
197         
198         StringReader in = new StringReader(xml);
199         HouseBeans newHouses = (HouseBeans) reader.parse(in);
200         assertNotNull("Parsing should return a bean", newHouses);
201         
202         ArrayList houseList = newHouses.houses;
203         assertEquals("Should be two houses read", 2, houseList.size());
204         HouseBean newOne = (HouseBean) houseList.get(0);
205         HouseBean newTwo = (HouseBean) houseList.get(1);
206         assertEquals("First house is equal",  houseOne, newOne);
207         assertEquals("Second house is equal",  houseTwo, newTwo);
208     }
209 }