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;
18  
19  
20  import java.beans.IntrospectionException;
21  import java.io.IOException;
22  import java.io.StringReader;
23  import java.io.StringWriter;
24  import java.util.ArrayList;
25  import java.util.Iterator;
26  import java.util.List;
27  
28  import org.apache.commons.betwixt.io.BeanReader;
29  import org.apache.commons.betwixt.io.BeanWriter;
30  import org.xml.sax.InputSource;
31  import org.xml.sax.SAXException;
32  
33  /**
34   * Tests the multi-mapping of collections with polymorphic entries.
35   * 
36   * @author Thomas Dudziak (tomdz@apache.org)
37   */
38  public class TestCollectionMapping extends AbstractTestCase
39  {
40      public static class Container
41      {
42          private List _elements = new ArrayList();
43  
44          public Iterator getElements()
45          {
46              return _elements.iterator();
47          }
48  
49          public void addElement(Element element)
50          {
51              _elements.add(element);
52          }
53      }
54  
55      public static interface Element
56      {}
57  
58      public static class ElementA implements Element
59      {}
60  
61      public static class ElementB implements Element
62      {}
63  
64      public static class ElementC
65      {}
66  
67      private static final String MAPPING =
68          "<?xml version=\"1.0\"?>\n"+
69          "<betwixt-config>\n"+
70          "  <class name=\"org.apache.commons.betwixt.TestCollectionMapping$Container\">\n"+
71          "    <element name=\"container\">\n"+
72          "      <element name=\"elements\">\n"+
73          "        <element property=\"elements\" updater='addElement'/>\n"+
74          "      </element>\n"+
75          "    </element>\n"+
76          "  </class>\n"+
77          "  <class name=\"org.apache.commons.betwixt.TestCollectionMapping$ElementA\">\n"+
78          "    <element name=\"elementA\"/>\n"+
79          "  </class>\n"+
80          "  <class name=\"org.apache.commons.betwixt.TestCollectionMapping$ElementB\">\n"+
81          "    <element name=\"elementB\"/>\n"+
82          "  </class>\n"+
83          "  <class name=\"org.apache.commons.betwixt.TestCollectionMapping$ElementC\">\n"+
84          "    <element name=\"elementC\"/>\n"+
85          "  </class>\n"+
86          "</betwixt-config>";
87      private static final String EXPECTED =
88          "<?xml version=\"1.0\" ?>\n"+
89          "  <container>\n"+
90          "    <elements>\n"+
91          "      <elementB/>\n"+
92          "      <elementA/>\n"+
93          "    </elements>\n"+
94          "  </container>\n";
95      private static final String INVALID_XML =
96          "<?xml version=\"1.0\" ?>\n"+
97          "  <container>\n"+
98          "    <elements>\n"+
99          "      <elementC/>\n"+
100         "    </elements>\n"+
101         "  </container>\n";
102     
103     public TestCollectionMapping(String testName)
104     {
105         super(testName);
106     }
107 
108     public void testRoundTripWithSingleMappingFile() throws IOException, SAXException, IntrospectionException
109     {
110         Container container = new Container();
111 
112         container.addElement(new ElementB());
113         container.addElement(new ElementA());
114 
115         StringWriter outputWriter = new StringWriter();
116 
117         outputWriter.write("<?xml version=\"1.0\" ?>\n");
118 
119         BeanWriter beanWriter = new BeanWriter(outputWriter);
120         beanWriter.setEndOfLine("\n");
121         beanWriter.enablePrettyPrint();
122         beanWriter.setWriteEmptyElements(true);
123         beanWriter.getBindingConfiguration().setMapIDs(false);
124         beanWriter.getXMLIntrospector().register(new InputSource(new StringReader(MAPPING)));
125         beanWriter.setEndOfLine("\n"); //force to \n so expected values match for sure
126         beanWriter.write(container);
127 
128         String output = outputWriter.toString();
129 
130         assertEquals(EXPECTED, output);
131             
132         BeanReader beanReader = new BeanReader();
133 
134         beanReader.registerMultiMapping(new InputSource(new StringReader(MAPPING)));
135 
136         StringReader xmlReader = new StringReader(output);
137 
138         container = (Container)beanReader.parse(xmlReader);
139 
140         Iterator it = container.getElements();
141 
142         assertTrue(it.next() instanceof ElementB);
143         assertTrue(it.next() instanceof ElementA);
144         assertFalse(it.hasNext());
145     }
146 
147     public void testInvalidXML() throws IOException, IntrospectionException, SAXException
148     {
149         BeanReader beanReader = new BeanReader();
150 
151         beanReader.registerMultiMapping(new InputSource(new StringReader(MAPPING)));
152 
153         StringReader xmlReader = new StringReader(INVALID_XML);
154         Container    container = (Container)beanReader.parse(xmlReader);
155 
156         // either we get an exception in the parse method (would perhaps be better)
157         // or the collection is empty (ElementC cannot be added)
158         assertFalse(container.getElements().hasNext());
159     }
160 }