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  package org.apache.commons.betwixt.schema;
19  
20  import java.io.StringReader;
21  import java.io.StringWriter;
22  import java.io.Writer;
23  
24  import junit.framework.Test;
25  import junit.framework.TestSuite;
26  
27  import org.apache.commons.betwixt.AbstractTestCase;
28  import org.apache.commons.betwixt.XMLIntrospector;
29  import org.apache.commons.betwixt.io.BeanReader;
30  import org.apache.commons.betwixt.io.BeanWriter;
31  import org.apache.commons.betwixt.registry.DefaultXMLBeanInfoRegistry;
32  import org.apache.commons.betwixt.strategy.DecapitalizeNameMapper;
33  import org.apache.commons.betwixt.strategy.HyphenatedNameMapper;
34  
35  //import org.apache.commons.logging.impl.SimpleLog;
36  //import org.apache.commons.betwixt.io.BeanRuleSet;
37  
38  /**
39   * This will test betwixt on handling a different kind of xml file, without
40   * a "collection" tag.
41   * 
42   * @author <a href="mailto:martin@mvdb.net">Martin van den Bemt</a>
43   * @version $Id: TestSchema.java 438373 2006-08-30 05:17:21Z bayard $
44   */
45  public class TestSchema extends AbstractTestCase
46  {
47      
48      public static Test suite()
49      {
50          return new TestSuite(TestSchema.class);
51      }
52  
53      
54      public TestSchema(String testName)
55      {
56          super(testName);
57      }
58      
59      /**
60       * Test the roundtrip with an xml file that doesn't have
61       * collection elements, writes it with collection elements
62       * and then compares the 2 object, which should end up
63       * equal..
64       */
65      public void testCombinedRoundTrip()
66      throws Exception
67      {	
68  //        SimpleLog log = new SimpleLog("[CombinedRoundTrip:BeanRuleSet]");
69  //        log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
70  //        BeanRuleSet.setLog(log);
71          
72  //        log = new SimpleLog("[CombinedRoundTrip]");
73  //        log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
74          
75          BeanReader reader = createBeanReader();
76          
77          PhysicalSchema schema = (PhysicalSchema) reader.parse(
78              getTestFileURL("src/test/org/apache/commons/betwixt/schema/schema.xml"));
79          StringWriter buffer = new StringWriter();
80          write(schema, buffer, true);
81          
82  //        log.debug(buffer.getBuffer().toString());
83          
84          StringReader in = new StringReader(buffer.getBuffer().toString());
85          reader = createBeanReader();
86          XMLIntrospector intro = createXMLIntrospector();
87          DefaultXMLBeanInfoRegistry registry = new DefaultXMLBeanInfoRegistry();
88          intro.setRegistry(registry);
89          // we have written the xml file back with element collections,
90          // so we have to say to the reader we want to use that now
91          // (the default when creating in this test is not to use them)
92          intro.getConfiguration().setWrapCollectionsInElement(true);
93          // first flush the cash, else setting other options, doesn't
94          // end up in rereading / mapping the object model.
95          registry.flush();
96          // set the xmlIntrospector back to the reader
97          reader.setXMLIntrospector(intro);
98          reader.deregisterBeanClass(PhysicalSchema.class);
99          reader.getRules().clear();
100         reader.registerBeanClass(PhysicalSchema.class);
101         PhysicalSchema schemaSecond = (PhysicalSchema) reader.parse(in);
102         buffer.close();
103         write(schema,buffer, true);
104         assertEquals(schema, schemaSecond);
105     }
106     /**
107      * Tests we can round trip from the XML -> bean -> XML -> bean.
108      * It will test if both object are identical.
109      * For this to actually work I implemented a details equals in my
110      * Beans..
111      */
112     public void testRoundTripWithoutCollectionElement()
113     throws Exception
114     {
115         BeanReader reader = createBeanReader();
116         PhysicalSchema schema = (PhysicalSchema) reader.parse(
117             getTestFileURL("src/test/org/apache/commons/betwixt/schema/schema.xml"));
118         StringWriter buffer = new StringWriter();
119         write(schema, buffer, false);
120         StringReader in = new StringReader(buffer.getBuffer().toString());
121         PhysicalSchema schemaSecond = (PhysicalSchema) reader.parse(in);
122         assertEquals(schemaSecond, schema);
123     }
124     
125     /**
126      * Creates a beanReader
127      */
128     protected BeanReader createBeanReader()
129     throws Exception
130      {
131         BeanReader reader = new BeanReader();
132         reader.setXMLIntrospector(createXMLIntrospector());
133         // register the class which maps to the root element
134         // of the xml file (this depends on the NameMapper used.
135         reader.registerBeanClass(PhysicalSchema.class);
136         return reader;
137     } 
138     
139     /**
140      * Set up the XMLIntroSpector
141      */
142     protected XMLIntrospector createXMLIntrospector() {
143         XMLIntrospector introspector = new XMLIntrospector();
144 
145         // set elements for attributes to true
146         introspector.getConfiguration().setAttributesForPrimitives(true);
147 
148         // Since we don't want to have collectionelements 
149         // line <DBMSS>, we have to set this to false,
150         // since the default is true.
151         introspector.getConfiguration().setWrapCollectionsInElement(false);
152 
153         // We have to use the HyphenatedNameMapper
154         // Since we want the names to resolve from eg PhysicalSchema
155         // to PHYSICAL_SCHEMA.
156         // we pass to the mapper we want uppercase and use _ for name
157         // seperation.
158         // This will set our ElementMapper.
159         introspector.getConfiguration().setElementNameMapper(new HyphenatedNameMapper(true, "_"));
160         // since our attribute names will use a different 
161         // naming convention in our xml file (just all lowercase)
162         // we set another mapper for the attributes
163         introspector.getConfiguration().setAttributeNameMapper(new DecapitalizeNameMapper());
164 
165         return introspector;
166     }
167     
168     /**
169      * Opens a writer and writes an object model according to the
170      * retrieved bean
171      */
172     private void write(Object bean, Writer out, boolean wrapCollectionsInElement)
173     throws Exception
174     {
175         BeanWriter writer = new BeanWriter(out);
176         writer.setWriteEmptyElements( true );
177         writer.setXMLIntrospector(createXMLIntrospector());
178         // specifies weather to use collection elements or not.
179         writer.getXMLIntrospector().getConfiguration().setWrapCollectionsInElement(wrapCollectionsInElement);
180         // we don't want to write Id attributes to every element
181         // we just want our opbject model written nothing more..
182         writer.getBindingConfiguration().setMapIDs(false);
183         // the source has 2 spaces indention and \n as line seperator.
184         writer.setIndent("  ");
185         writer.setEndOfLine("\n");
186         writer.write(bean);
187     }
188 }
189