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   
18  
19  package org.apache.commons.betwixt.strategy;
20  
21  import java.io.StringReader;
22  import java.io.StringWriter;
23  import java.util.ArrayList;
24  import java.util.Collection;
25  
26  import org.apache.commons.betwixt.AbstractTestCase;
27  import org.apache.commons.betwixt.AttributeDescriptor;
28  import org.apache.commons.betwixt.ElementDescriptor;
29  import org.apache.commons.betwixt.IntrospectionConfiguration;
30  import org.apache.commons.betwixt.XMLBeanInfo;
31  import org.apache.commons.betwixt.XMLIntrospector;
32  import org.apache.commons.betwixt.io.BeanReader;
33  import org.apache.commons.betwixt.io.BeanWriter;
34  
35  /**
36   * Tests for SimpleTypeMapper and the associated strategy.
37   * @author <a href='http://commons.apache.org/'>Apache Commons Team</a>
38   * @version $Revision: 561314 $
39   */
40  public class TestSimpleTypeMapper extends AbstractTestCase {
41  
42      public TestSimpleTypeMapper(String name) {
43          super(name);
44      }
45      
46      public void testDefaultExceptionType() throws Exception {
47           assertEquals(TypeBindingStrategy.BindingType.COMPLEX, TypeBindingStrategy.DEFAULT.bindingType(RuntimeException.class));
48      }
49      
50      public void testNewStrategy() throws Exception {
51          XMLIntrospector introspector = new XMLIntrospector();
52          introspector.getConfiguration().setSimpleTypeMapper(new StringsAsElementsSimpleTypeMapper());
53          introspector.getConfiguration().setWrapCollectionsInElement(true);
54          
55          XMLBeanInfo beanInfo = introspector.introspect(TuneBean.class);
56          ElementDescriptor tuneBeanDescriptor = beanInfo.getElementDescriptor();
57          
58          AttributeDescriptor[] tuneBeanAttributes = tuneBeanDescriptor.getAttributeDescriptors();
59          assertEquals("Only expect one attribute", 1, tuneBeanAttributes.length);
60          AttributeDescriptor recordedAttribute = tuneBeanAttributes[0];
61          assertEquals("Expected recorded to be bound as an attribute", "recorded", recordedAttribute.getLocalName());
62          
63          ElementDescriptor[] tuneBeanChildElements = tuneBeanDescriptor.getElementDescriptors();
64          assertEquals("Expected three child elements", 3 , tuneBeanChildElements.length);
65          
66          int bits = 0;
67          for (int i=0, size=tuneBeanChildElements.length; i<size; i++) {
68              String localName = tuneBeanChildElements[i].getLocalName();
69              if ("composers".equals(localName)) {
70                  bits = bits | 1;
71              }
72              if ("artist".equals(localName)) {
73                  bits = bits | 2;
74              }      
75              if ("name".equals(localName)) {
76                  bits = bits | 4;
77              }          
78          }
79          
80          assertEquals("Every element present", 7, bits);
81      }
82      
83      public void testWrite() throws Exception {
84          StringWriter out = new StringWriter();
85          out.write("<?xml version='1.0'?>");
86          BeanWriter writer = new BeanWriter(out);
87          writer.getXMLIntrospector().getConfiguration().setSimpleTypeMapper(new StringsAsElementsSimpleTypeMapper());
88          writer.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(true);
89          writer.getBindingConfiguration().setMapIDs(false);
90          
91          TuneBean bean = new TuneBean("On The Run", "Pink Floyd", 1972);
92          bean.addComposer(new ComposerBean("David", "Gilmour", 1944));
93          bean.addComposer(new ComposerBean("Roger", "Waters", 1944));
94          
95          writer.write(bean);
96          
97          String xml = out.getBuffer().toString();
98          String expected = "<?xml version='1.0'?>" +
99              "<TuneBean recorded='1972'>" +
100             "    <name>On The Run</name>" +
101             "    <artist>Pink Floyd</artist>" +
102             "    <composers>" +
103             "       <composer born='1944'>" +
104             "           <forename>David</forename>" +
105             "           <surname>Gilmour</surname>" +
106             "       </composer>" +
107             "       <composer born='1944'>" +
108             "           <forename>Roger</forename>" +
109             "           <surname>Waters</surname>" +
110             "       </composer>" +
111             "   </composers>" +
112             "</TuneBean>";
113         
114         xmlAssertIsomorphicContent(parseString(xml), parseString(expected), true);
115     }
116     
117     public void testRead() throws Exception {
118         
119         String xml = "<?xml version='1.0'?>" +
120             "<TuneBean recorded='1972'>" +
121             "    <name>On The Run</name>" +
122             "    <artist>Pink Floyd</artist>" +
123             "    <composers>" +
124             "       <composer born='1944'>" +
125             "           <forename>David</forename>" +
126             "           <surname>Gilmour</surname>" +
127             "       </composer>" +
128             "       <composer born='1944'>" +
129             "           <forename>Roger</forename>" +
130             "           <surname>Waters</surname>" +
131             "       </composer>" +
132             "   </composers>" +
133             "</TuneBean>";
134        StringReader in = new StringReader(xml);
135        
136        BeanReader reader = new BeanReader();
137        reader.getXMLIntrospector().getConfiguration().setSimpleTypeMapper(new StringsAsElementsSimpleTypeMapper());
138        reader.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(true);
139        reader.getBindingConfiguration().setMapIDs(false);
140        
141        reader.registerBeanClass(TuneBean.class);
142        
143        TuneBean bean = (TuneBean) reader.parse(in);
144        
145        assertNotNull("Parsing failed", bean);
146        assertEquals("Name value", "On The Run", bean.getName());
147        assertEquals("Artist value", "Pink Floyd", bean.getArtist());
148        assertEquals("Recorded value", 1972, bean.getRecorded());
149        
150        Collection expectedComposers = new ArrayList();
151        expectedComposers.add(new ComposerBean("David", "Gilmour", 1944));
152        expectedComposers.add(new ComposerBean("Roger", "Waters", 1944));
153        
154        assertTrue("Right composers", bean.sameComposers(expectedComposers));
155     }
156         
157     /** Implementation binds strings to elements but everything else to attributes */
158     class StringsAsElementsSimpleTypeMapper extends SimpleTypeMapper {
159 
160         /**
161          * Binds strings to elements but everything else to attributes
162          */
163         public Binding bind(
164                             String propertyName, 
165                             Class propertyType, 
166                             IntrospectionConfiguration configuration) {
167             if (String.class.equals(propertyType)) {
168                 return SimpleTypeMapper.Binding.ELEMENT;
169             }
170             return SimpleTypeMapper.Binding.ATTRIBUTE;
171         }
172                
173     }
174 }