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 155402 2005-02-26 12:52:00Z dirkv $
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.getBindingConfiguration().setMapIDs(false);
64          writer.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(true);
65          writer.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(false);
66          writer.write("houses", houses);
67          
68          String xml = "<?xml version='1.0'?><houses>"
69              + "<house tenant='false'>"
70              + "<address street='Black Bull, 46 Briggate' city='Brighouse' country='England' code='HD6 1EF'/>"
71              + "<householder forename='Samual' surname='Smith'/>"
72              + "<facing name='North'/>"
73              + "</house>"
74              + "<house tenant='true'>"
75              + "<address street='The Commerical Inn, 1 Gooder Lane' city='Brighouse'" 
76              + " country='England' code='HD6 1HT'/>"
77              + "<householder forename='Timothy' surname='Tayler'/>"
78              + "<facing name='South'/>"
79              + "</house>"
80              + "</houses>";
81          
82          xmlAssertIsomorphic(parseString(xml), parseString(out.toString()), true);
83  
84          BeanCreationList chain = BeanCreationList.createStandardChain();
85          // add a filter that creates enums to the start
86          
87          class EnumCreator implements ChainedBeanCreator {
88              
89              public Object create(ElementMapping mapping, ReadContext context, BeanCreationChain chain) {
90                  if ("facing".equals(mapping.getName())) {
91                      String value = mapping.getAttributes().getValue("name");
92                      if ("North".equals(value)) {
93                          return CompassPoint.NORTH;
94                      }
95                      if ("South".equals(value)) {
96                          return CompassPoint.SOUTH;
97                      }
98                      if ("East".equals(value)) {
99                          return CompassPoint.EAST;
100                     }
101                     if ("West".equals(value)) {
102                         return CompassPoint.WEST;
103                     }
104                 }
105                 return chain.create(mapping, context);
106             }
107         }
108         chain.insertBeanCreator(1, new EnumCreator());
109         
110         BeanReader reader = new BeanReader();
111         reader.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(true);
112         reader.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(false);
113         reader.registerBeanClass("houses", HouseBeans.class);
114         reader.getReadConfiguration().setBeanCreationChain(chain);
115         
116         StringReader in = new StringReader(xml);
117         HouseBeans newHouses = (HouseBeans) reader.parse(in);
118         assertNotNull("Parsing should return a bean", newHouses);
119         
120         ArrayList houseList = newHouses.houses;
121         assertEquals("Should be two houses read", 2, houseList.size());
122         HouseBean newOne = (HouseBean) houseList.get(0);
123         HouseBean newTwo = (HouseBean) houseList.get(1);
124         assertEquals("First house is equal",  houseOne, newOne);
125         assertEquals("Second house is equal",  houseTwo, newTwo);
126         
127     }
128     
129     public void testCustomCreatorTwo() throws Exception {
130         HouseBeans houses = new HouseBeans();
131         HouseBean houseOne = new HouseBean();
132         houseOne.setFacing(CompassPoint.NORTH);
133         houseOne.setAddress(new AddressBean("Black Bull, 46 Briggate", "Brighouse", "England", "HD6 1EF"));
134         houseOne.setHouseholder(new PersonBean("Samual", "Smith"));
135         houseOne.setTenant(false);
136         houses.addHouse(houseOne);
137         HouseBean houseTwo = new HouseBean();
138         houseTwo.setFacing(CompassPoint.SOUTH);
139         houseTwo.setAddress(new AddressBean("The Commerical Inn, 1 Gooder Lane", "Brighouse", "England", "HD6 1HT"));
140         houseTwo.setHouseholder(new PersonBean("Timothy", "Tayler"));
141         houseTwo.setTenant(true);
142         houses.addHouse(houseTwo);
143         
144         StringWriter out = new StringWriter();
145         out.write("<?xml version='1.0'?>");
146         BeanWriter writer = new BeanWriter(out);
147 		writer.getBindingConfiguration().setMapIDs(false);
148         writer.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(true);
149         writer.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(false);
150         writer.write("houses", houses);
151         
152         String xml = "<?xml version='1.0'?><houses>"
153             + "<house tenant='false'>"
154             + "<address street='Black Bull, 46 Briggate' city='Brighouse' country='England' code='HD6 1EF'/>"
155             + "<householder forename='Samual' surname='Smith'/>"
156             + "<facing name='North'/>"
157             + "</house>"
158             + "<house tenant='true'>"
159             + "<address street='The Commerical Inn, 1 Gooder Lane' city='Brighouse'" 
160             + " country='England' code='HD6 1HT'/>"
161             + "<householder forename='Timothy' surname='Tayler'/>"
162             + "<facing name='South'/>"
163             + "</house>"
164             + "</houses>";
165         
166         xmlAssertIsomorphic(parseString(xml), parseString(out.toString()), true);
167 
168         BeanCreationList chain = BeanCreationList.createStandardChain();
169         // add a filter that creates enums to the start
170         
171         class EnumCreator implements ChainedBeanCreator {
172             // match by class this time
173             public Object create(ElementMapping mapping, ReadContext context, BeanCreationChain chain) {
174                 if (CompassPoint.class.equals(mapping.getType())) {
175                     String value = mapping.getAttributes().getValue("name");
176                     if ("North".equals(value)) {
177                         return CompassPoint.NORTH;
178                     }
179                     if ("South".equals(value)) {
180                         return CompassPoint.SOUTH;
181                     }
182                     if ("East".equals(value)) {
183                         return CompassPoint.EAST;
184                     }
185                     if ("West".equals(value)) {
186                         return CompassPoint.WEST;
187                     }
188                 }
189                 return chain.create(mapping, context);
190             }
191         }
192         chain.insertBeanCreator(1, new EnumCreator());
193         
194         BeanReader reader = new BeanReader();
195         reader.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(true);
196         reader.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(false);
197         reader.registerBeanClass("houses", HouseBeans.class);
198         reader.getReadConfiguration().setBeanCreationChain(chain);
199         
200         StringReader in = new StringReader(xml);
201         HouseBeans newHouses = (HouseBeans) reader.parse(in);
202         assertNotNull("Parsing should return a bean", newHouses);
203         
204         ArrayList houseList = newHouses.houses;
205         assertEquals("Should be two houses read", 2, houseList.size());
206         HouseBean newOne = (HouseBean) houseList.get(0);
207         HouseBean newTwo = (HouseBean) houseList.get(1);
208         assertEquals("First house is equal",  houseOne, newOne);
209         assertEquals("Second house is equal",  houseTwo, newTwo);
210     }
211 }