1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */ 
17  package org.apache.commons.betwixt.io.read;
18  
19  import java.io.StringReader;
20  import java.io.StringWriter;
21  import java.util.ArrayList;
22  
23  import junit.framework.Test;
24  import junit.framework.TestSuite;
25  
26  import org.apache.commons.betwixt.AbstractTestCase;
27  import org.apache.commons.betwixt.io.BeanReader;
28  import org.apache.commons.betwixt.io.BeanWriter;
29  
30  /** 
31   * Test harness for bean creation (during reading).
32   * 
33   * @author Robert Burrell Donkin
34   * @version $Id: TestBeanCreation.java 438373 2006-08-30 05:17:21Z bayard $
35   */
36  public class TestBeanCreation extends AbstractTestCase {
37  
38      public TestBeanCreation(String name) {
39          super(name);
40      }
41          
42      public static Test suite() {
43          return new TestSuite(TestBeanCreation.class);
44      }    
45      
46      public void testCustomCreatorOne() throws Exception {
47          HouseBeans houses = new HouseBeans();
48          HouseBean houseOne = new HouseBean();
49          houseOne.setFacing(CompassPoint.NORTH);
50          houseOne.setAddress(new AddressBean("Black Bull, 46 Briggate", "Brighouse", "England", "HD6 1EF"));
51          houseOne.setHouseholder(new PersonBean("Samual", "Smith"));
52          houseOne.setTenant(false);
53          houses.addHouse(houseOne);
54          HouseBean houseTwo = new HouseBean();
55          houseTwo.setFacing(CompassPoint.SOUTH);
56          houseTwo.setAddress(new AddressBean("The Commerical Inn, 1 Gooder Lane", "Brighouse", "England", "HD6 1HT"));
57          houseTwo.setHouseholder(new PersonBean("Timothy", "Tayler"));
58          houseTwo.setTenant(true);
59          houses.addHouse(houseTwo);
60          
61          StringWriter out = new StringWriter();
62          out.write("<?xml version='1.0'?>");
63          BeanWriter writer = new BeanWriter(out);
64  		writer.getBindingConfiguration().setMapIDs(false);
65          writer.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(true);
66          writer.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(false);
67          writer.write("houses", houses);
68          
69          String xml = "<?xml version='1.0'?><houses>"
70              + "<house tenant='false'>"
71              + "<address street='Black Bull, 46 Briggate' city='Brighouse' country='England' code='HD6 1EF'/>"
72              + "<householder forename='Samual' surname='Smith'/>"
73              + "<facing name='North'/>"
74              + "</house>"
75              + "<house tenant='true'>"
76              + "<address street='The Commerical Inn, 1 Gooder Lane' city='Brighouse'" 
77              + " country='England' code='HD6 1HT'/>"
78              + "<householder forename='Timothy' surname='Tayler'/>"
79              + "<facing name='South'/>"
80              + "</house>"
81              + "</houses>";
82          
83          xmlAssertIsomorphic(parseString(xml), parseString(out.toString()), true);
84  
85          BeanCreationList chain = BeanCreationList.createStandardChain();
86          // add a filter that creates enums to the start
87          
88          class EnumCreator implements ChainedBeanCreator {
89              
90              public Object create(ElementMapping mapping, ReadContext context, BeanCreationChain chain) {
91                  if ("facing".equals(mapping.getName())) {
92                      String value = mapping.getAttributes().getValue("name");
93                      if ("North".equals(value)) {
94                          return CompassPoint.NORTH;
95                      }
96                      if ("South".equals(value)) {
97                          return CompassPoint.SOUTH;
98                      }
99                      if ("East".equals(value)) {
100                         return CompassPoint.EAST;
101                     }
102                     if ("West".equals(value)) {
103                         return CompassPoint.WEST;
104                     }
105                 }
106                 return chain.create(mapping, context);
107             }
108         }
109         chain.insertBeanCreator(1, new EnumCreator());
110         
111         BeanReader reader = new BeanReader();
112         reader.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(true);
113         reader.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(false);
114         reader.registerBeanClass("houses", HouseBeans.class);
115         reader.getReadConfiguration().setBeanCreationChain(chain);
116         
117         StringReader in = new StringReader(xml);
118         HouseBeans newHouses = (HouseBeans) reader.parse(in);
119         assertNotNull("Parsing should return a bean", newHouses);
120         
121         ArrayList houseList = newHouses.houses;
122         assertEquals("Should be two houses read", 2, houseList.size());
123         HouseBean newOne = (HouseBean) houseList.get(0);
124         HouseBean newTwo = (HouseBean) houseList.get(1);
125         assertEquals("First house is equal",  houseOne, newOne);
126         assertEquals("Second house is equal",  houseTwo, newTwo);
127         
128     }
129     
130     public void testCustomCreatorTwo() throws Exception {
131         HouseBeans houses = new HouseBeans();
132         HouseBean houseOne = new HouseBean();
133         houseOne.setFacing(CompassPoint.NORTH);
134         houseOne.setAddress(new AddressBean("Black Bull, 46 Briggate", "Brighouse", "England", "HD6 1EF"));
135         houseOne.setHouseholder(new PersonBean("Samual", "Smith"));
136         houseOne.setTenant(false);
137         houses.addHouse(houseOne);
138         HouseBean houseTwo = new HouseBean();
139         houseTwo.setFacing(CompassPoint.SOUTH);
140         houseTwo.setAddress(new AddressBean("The Commerical Inn, 1 Gooder Lane", "Brighouse", "England", "HD6 1HT"));
141         houseTwo.setHouseholder(new PersonBean("Timothy", "Tayler"));
142         houseTwo.setTenant(true);
143         houses.addHouse(houseTwo);
144         
145         StringWriter out = new StringWriter();
146         out.write("<?xml version='1.0'?>");
147         BeanWriter writer = new BeanWriter(out);
148 		writer.getBindingConfiguration().setMapIDs(false);
149         writer.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(true);
150         writer.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(false);
151         writer.write("houses", houses);
152         
153         String xml = "<?xml version='1.0'?><houses>"
154             + "<house tenant='false'>"
155             + "<address street='Black Bull, 46 Briggate' city='Brighouse' country='England' code='HD6 1EF'/>"
156             + "<householder forename='Samual' surname='Smith'/>"
157             + "<facing name='North'/>"
158             + "</house>"
159             + "<house tenant='true'>"
160             + "<address street='The Commerical Inn, 1 Gooder Lane' city='Brighouse'" 
161             + " country='England' code='HD6 1HT'/>"
162             + "<householder forename='Timothy' surname='Tayler'/>"
163             + "<facing name='South'/>"
164             + "</house>"
165             + "</houses>";
166         
167         xmlAssertIsomorphic(parseString(xml), parseString(out.toString()), true);
168 
169         BeanCreationList chain = BeanCreationList.createStandardChain();
170         // add a filter that creates enums to the start
171         
172         class EnumCreator implements ChainedBeanCreator {
173             // match by class this time
174             public Object create(ElementMapping mapping, ReadContext context, BeanCreationChain chain) {
175                 if (CompassPoint.class.equals(mapping.getType())) {
176                     String value = mapping.getAttributes().getValue("name");
177                     if ("North".equals(value)) {
178                         return CompassPoint.NORTH;
179                     }
180                     if ("South".equals(value)) {
181                         return CompassPoint.SOUTH;
182                     }
183                     if ("East".equals(value)) {
184                         return CompassPoint.EAST;
185                     }
186                     if ("West".equals(value)) {
187                         return CompassPoint.WEST;
188                     }
189                 }
190                 return chain.create(mapping, context);
191             }
192         }
193         chain.insertBeanCreator(1, new EnumCreator());
194         
195         BeanReader reader = new BeanReader();
196         reader.getXMLIntrospector().getConfiguration().setAttributesForPrimitives(true);
197         reader.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(false);
198         reader.registerBeanClass("houses", HouseBeans.class);
199         reader.getReadConfiguration().setBeanCreationChain(chain);
200         
201         StringReader in = new StringReader(xml);
202         HouseBeans newHouses = (HouseBeans) reader.parse(in);
203         assertNotNull("Parsing should return a bean", newHouses);
204         
205         ArrayList houseList = newHouses.houses;
206         assertEquals("Should be two houses read", 2, houseList.size());
207         HouseBean newOne = (HouseBean) houseList.get(0);
208         HouseBean newTwo = (HouseBean) houseList.get(1);
209         assertEquals("First house is equal",  houseOne, newOne);
210         assertEquals("Second house is equal",  houseTwo, newTwo);
211     }
212 }