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.introspection;
19  
20  import java.beans.BeanInfo;
21  import java.beans.Introspector;
22  import java.beans.PropertyDescriptor;
23  import java.io.StringWriter;
24  
25  import junit.framework.Test;
26  import junit.framework.TestSuite;
27  import junit.textui.TestRunner;
28  
29  import org.apache.commons.betwixt.AbstractTestCase;
30  import org.apache.commons.betwixt.AttributeDescriptor;
31  import org.apache.commons.betwixt.ElementDescriptor;
32  import org.apache.commons.betwixt.XMLBeanInfo;
33  import org.apache.commons.betwixt.XMLIntrospector;
34  import org.apache.commons.betwixt.io.BeanWriter;
35  import org.apache.commons.betwixt.registry.DefaultXMLBeanInfoRegistry;
36  import org.apache.commons.betwixt.registry.NoCacheRegistry;
37  import org.apache.commons.betwixt.strategy.ClassNormalizer;
38  import org.apache.commons.betwixt.strategy.ListedClassNormalizer;
39  import org.apache.commons.digester.rss.Channel;
40  
41  
42  /*** Test harness for the XMLIntrospector
43    *
44    * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
45    * @version $Revision: 438373 $
46    */
47  public class TestXMLIntrospector extends AbstractTestCase {
48      
49      public static void main( String[] args ) {
50          TestRunner.run( suite() );
51      }
52      
53      public static Test suite() {
54          return new TestSuite(TestXMLIntrospector.class);
55      }
56          
57      public TestXMLIntrospector(String testName) {
58          super(testName);
59      }
60      
61      public void testIntrospector() throws Exception {
62          //SimpleLog log = new SimpleLog("testIntrospector:introspector");
63          //log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
64          XMLIntrospector introspector = new XMLIntrospector();
65          //introspector.setLog(log);
66          
67          introspector.getConfiguration().setAttributesForPrimitives(true);
68          
69          Object bean = createBean();
70          
71          XMLBeanInfo info = introspector.introspect( bean );
72          
73          assertTrue( "Found XMLBeanInfo", info != null );
74          
75          ElementDescriptor descriptor = info.getElementDescriptor();
76          
77          assertTrue( "Found root element descriptor", descriptor != null );
78          
79          AttributeDescriptor[] attributes = descriptor.getAttributeDescriptors();
80          
81          assertTrue( "Found attributes", attributes != null && attributes.length > 0 );
82          
83          // test second introspection with caching on
84          info = introspector.introspect( bean );
85          
86          assertTrue( "Found XMLBeanInfo", info != null );
87          
88          descriptor = info.getElementDescriptor();
89          
90          assertTrue( "Found root element descriptor", descriptor != null );
91          
92          attributes = descriptor.getAttributeDescriptors();
93          
94          assertTrue( "Found attributes", attributes != null && attributes.length > 0 );
95  
96  
97          // test introspection with caching off      
98          //introspector.setCachingEnabled(false);  
99          introspector.setRegistry(new NoCacheRegistry());
100         info = introspector.introspect( bean );
101         
102         assertTrue( "Found XMLBeanInfo", info != null );
103         
104         descriptor = info.getElementDescriptor();
105         
106         assertTrue( "Found root element descriptor", descriptor != null );
107         
108         attributes = descriptor.getAttributeDescriptors();
109         
110         assertTrue( "Found attributes", attributes != null && attributes.length > 0 );
111 
112 
113         // test introspection after flushing cache
114 //        introspector.setCachingEnabled(true);
115         introspector.setRegistry(new DefaultXMLBeanInfoRegistry()); 
116         //introspector.flushCache();
117         info = introspector.introspect( bean );
118         
119         assertTrue( "Found XMLBeanInfo", info != null );
120         
121         descriptor = info.getElementDescriptor();
122         
123         assertTrue( "Found root element descriptor", descriptor != null );
124         
125         attributes = descriptor.getAttributeDescriptors();
126         
127         assertTrue( "Found attributes", attributes != null && attributes.length > 0 );
128 
129     }
130     
131     public void testBeanWithBeanInfo() throws Exception {
132         
133         // let's check that bean info's ok
134         BeanInfo bwbiBeanInfo = Introspector.getBeanInfo(BeanWithBeanInfoBean.class);
135         
136         PropertyDescriptor[] propertyDescriptors = bwbiBeanInfo.getPropertyDescriptors();
137 
138         assertEquals("Wrong number of properties", 2 , propertyDescriptors.length);
139         
140         // order of properties isn't guarenteed 
141         if ("alpha".equals(propertyDescriptors[0].getName())) {
142         
143             assertEquals("Second property name", "gamma" , propertyDescriptors[1].getName());
144             
145         } else {
146         
147             assertEquals("First property name", "gamma" , propertyDescriptors[0].getName());
148             assertEquals("Second property name", "alpha" , propertyDescriptors[1].getName());
149         }
150         
151         // finished with the descriptors
152         propertyDescriptors = null;
153 
154 //        SimpleLog log = new SimpleLog("[testBeanWithBeanInfo:XMLIntrospector]");
155 //        log.setLevel(SimpleLog.LOG_LEVEL_TRACE);
156 
157         XMLIntrospector introspector = new XMLIntrospector();
158         introspector.getConfiguration().setAttributesForPrimitives(false);
159 //        introspector.setLog(log);
160         
161         XMLBeanInfo xmlBeanInfo = introspector.introspect(BeanWithBeanInfoBean.class);
162         
163         ElementDescriptor[] elementDescriptors = xmlBeanInfo.getElementDescriptor().getElementDescriptors();
164         
165 //        log = new SimpleLog("[testBeanWithBeanInfo]");
166 //        log.setLevel(SimpleLog.LOG_LEVEL_DEBUG);
167         
168 //        log.debug("XMLBeanInfo:");
169 //        log.debug(xmlBeanInfo);
170 //        log.debug("Elements:");
171 //        log.debug(elementDescriptors[0].getPropertyName());
172 //        log.debug(elementDescriptors[1].getPropertyName());
173         
174         assertEquals("Wrong number of elements", 2 , elementDescriptors.length);
175 
176         // order of properties isn't guarenteed 
177         boolean alphaFirst = true;
178         if ("alpha".equals(elementDescriptors[0].getPropertyName())) {
179             
180             assertEquals("Second element name", "gamma" , elementDescriptors[1].getPropertyName());
181             
182         } else {
183             alphaFirst = false;
184             assertEquals("First element name", "gamma" , elementDescriptors[0].getPropertyName());
185             assertEquals("Second element name", "alpha" , elementDescriptors[1].getPropertyName());
186         }
187         
188         // might as well give test output
189         StringWriter out = new StringWriter();
190         BeanWriter writer = new BeanWriter(out);
191         writer.getBindingConfiguration().setMapIDs(false);
192         BeanWithBeanInfoBean bean = new BeanWithBeanInfoBean("alpha value","beta value","gamma value");
193         writer.write(bean);
194         
195         if (alphaFirst) {
196         
197             xmlAssertIsomorphicContent(
198                     parseFile("src/test/org/apache/commons/betwixt/introspection/test-bwbi-output-a.xml"),
199                     parseString(out.toString()));
200         
201         } else {
202             xmlAssertIsomorphicContent(
203                     parseFile("src/test/org/apache/commons/betwixt/introspection/test-bwbi-output-g.xml"),
204                     parseString(out.toString()));
205         }
206     }
207     
208     public void testDefaultClassNormalizer() throws Exception {
209         XMLIntrospector introspector = new XMLIntrospector();
210         
211         FaceImpl face = new FaceImpl();
212         XMLBeanInfo info = introspector.introspect( face );
213         ElementDescriptor elementDescriptor = info.getElementDescriptor();
214     
215         AttributeDescriptor[] attributeDescriptor = elementDescriptor.getAttributeDescriptors();      
216         ElementDescriptor[] children = elementDescriptor.getElementDescriptors();
217         
218         assertEquals("Expected no attributes", 0, attributeDescriptor.length);
219         assertEquals("Expected two elements", 2, children.length);
220     }	
221     
222     public void testClassNormalizer() throws Exception {
223         XMLIntrospector introspector = new XMLIntrospector();
224         introspector.getConfiguration().setClassNormalizer( new ClassNormalizer() {
225                 
226                 public Class normalize(Class clazz) {
227                     if (IFace.class.isAssignableFrom( clazz )) {
228                         return IFace.class;
229                     }	
230                     return super.normalize( clazz );
231                 }	
232             });
233         
234         FaceImpl face = new FaceImpl();
235         XMLBeanInfo info = introspector.introspect( face );
236         ElementDescriptor elementDescriptor = info.getElementDescriptor();
237         assertEquals("Expected only itself", 1, elementDescriptor.getElementDescriptors().length);
238     
239         AttributeDescriptor[] attributeDescriptor = elementDescriptor.getAttributeDescriptors();      
240         ElementDescriptor[] children = elementDescriptor.getElementDescriptors();
241         
242         assertEquals("Expected no attributes", 0, attributeDescriptor.length);
243         assertEquals("Expected one elements", 1, children.length);
244         assertEquals("Expected element", "name", children[0].getLocalName());
245     }	
246     
247     public void testListedClassNormalizer() throws Exception {
248         ListedClassNormalizer classNormalizer = new ListedClassNormalizer();
249         classNormalizer.addSubstitution( IFace.class );
250         XMLIntrospector introspector = new XMLIntrospector();
251         introspector.getConfiguration().setClassNormalizer(classNormalizer);
252         
253         FaceImpl face = new FaceImpl();
254         
255         XMLBeanInfo info = introspector.introspect( face );
256         ElementDescriptor elementDescriptor = info.getElementDescriptor();
257         AttributeDescriptor[] attributeDescriptor = elementDescriptor.getAttributeDescriptors();      
258         ElementDescriptor[] children = elementDescriptor.getElementDescriptors();
259         
260         assertEquals("Expected no attributes", 0, attributeDescriptor.length);
261         assertEquals("Expected one elements", 1, children.length);
262         assertEquals("Expected element", "name", children[0].getLocalName());
263     }	    
264     
265     public void testListedClassNormalizerWrite() throws Exception {
266         ListedClassNormalizer classNormalizer = new ListedClassNormalizer();
267         classNormalizer.addSubstitution( IFace.class );
268         
269         StringWriter out = new StringWriter();
270         out.write("<?xml version='1.0'?>");
271         BeanWriter writer = new BeanWriter( out );
272 		writer.getBindingConfiguration().setMapIDs(false);
273         writer.getXMLIntrospector().getConfiguration().setClassNormalizer( classNormalizer );
274         FaceImpl bean = new FaceImpl();
275         bean.setName("Old Tom Cobbly");
276         writer.write(bean);
277         
278         String xml="<?xml version='1.0'?><IFace><name>Old Tom Cobbly</name></IFace>";
279         xmlAssertIsomorphicContent(
280                             parseString(out.getBuffer().toString()),
281                             parseString(xml), 
282                             true);
283     }	
284     
285     public void testBetwixtFileType() throws Exception {
286     	XMLIntrospector introspector = new XMLIntrospector();
287     	XMLBeanInfo info = introspector.introspect( Channel.class );
288     	
289     	ElementDescriptor elementDescriptor = info.getElementDescriptor();
290     	
291 		Class clazz = elementDescriptor.getSingularPropertyType();
292 		assertEquals( "Element type correct", Channel.class , clazz);
293 		
294 		assertEquals( "Element name correct", "rss", elementDescriptor.getLocalName());
295     }
296     
297     public void testIgnoreAllBeanInfo() throws Exception {
298         XMLIntrospector introspector = new XMLIntrospector();
299         introspector.getConfiguration().setIgnoreAllBeanInfo( false );
300         introspector.setRegistry(new NoCacheRegistry());
301         XMLBeanInfo info = introspector.introspect( BeanWithBeanInfoBean.class ); 
302         ElementDescriptor[] elementDescriptors = info.getElementDescriptor().getElementDescriptors();
303         // When BeanInfo is used the properties alpha and gamma will be found 
304         if ("alpha".equals(elementDescriptors[0].getPropertyName())) {
305             assertEquals("Second element name", "gamma" , elementDescriptors[1].getPropertyName());
306         } else {
307             assertEquals("First element name", "gamma" , elementDescriptors[0].getPropertyName());
308             assertEquals("Second element name", "alpha" , elementDescriptors[1].getPropertyName());
309         }
310 
311         introspector.getConfiguration().setIgnoreAllBeanInfo( true );
312         info = introspector.introspect( BeanWithBeanInfoBean.class ); 
313         elementDescriptors = info.getElementDescriptor().getElementDescriptors();
314         // When BeanInfo is ignored the properties alpha and beta will be found
315         if ("alpha".equals(elementDescriptors[0].getPropertyName())) {
316             assertEquals("Second element name", "beta" , elementDescriptors[1].getPropertyName());
317         } else {
318             assertEquals("First element name", "beta" , elementDescriptors[0].getPropertyName());
319             assertEquals("Second element name", "alpha" , elementDescriptors[1].getPropertyName());
320         }
321     }
322     
323 
324 }
325