1   /*
2    * Copyright (C) The MetaClass Group. All rights reserved.
3    *
4    * This software is published under the terms of the Spice
5    * Software License version 1.1, a copy of which has been included
6    * with this distribution in the LICENSE.txt file.
7    */
8   package org.codehaus.metaclass.io;
9   
10  import java.util.Properties;
11  import javax.xml.parsers.DocumentBuilder;
12  import javax.xml.parsers.DocumentBuilderFactory;
13  import junit.framework.TestCase;
14  import org.codehaus.metaclass.model.Attribute;
15  import org.codehaus.metaclass.model.ClassDescriptor;
16  import org.codehaus.metaclass.model.FieldDescriptor;
17  import org.codehaus.metaclass.model.MethodDescriptor;
18  import org.codehaus.metaclass.model.ParameterDescriptor;
19  import org.w3c.dom.Comment;
20  import org.w3c.dom.Document;
21  import org.w3c.dom.Element;
22  import org.w3c.dom.Text;
23  
24  /***
25   * @author Peter Donald
26   * @version $Revision: 1.14 $ $Date: 2003/11/28 11:14:54 $
27   */
28  public class DOMMetaClassDeserializerTestCase
29      extends TestCase
30  {
31      public void testGetPathDescriptionOneLevelDeep()
32          throws Exception
33      {
34          final DOMMetaClassDeserializer deserializer = new DOMMetaClassDeserializer();
35          final Document document = createDocument();
36          final Element element = document.createElement( "foo" );
37          final String description = deserializer.getPathDescription( element );
38          assertEquals( "description", "foo", description );
39      }
40  
41      public void testGetPathDescriptionMultipleLevelsDeep()
42          throws Exception
43      {
44          final DOMMetaClassDeserializer deserializer = new DOMMetaClassDeserializer();
45          final Document document = createDocument();
46          final Element element = document.createElement( "foo" );
47          final Element child = document.createElement( "baz" );
48          element.appendChild( child );
49          final String description = deserializer.getPathDescription( child );
50          assertEquals( "description", "foo/baz", description );
51      }
52  
53      public void testExpectElementThatIsPresent()
54          throws Exception
55      {
56          final DOMMetaClassDeserializer deserializer = new DOMMetaClassDeserializer();
57          final Document document = createDocument();
58          final Element element = document.createElement( "foo" );
59          deserializer.expectElement( element, "foo" );
60      }
61  
62      public void testExpectElementThatIsNotPresent()
63          throws Exception
64      {
65          final DOMMetaClassDeserializer deserializer = new DOMMetaClassDeserializer();
66          final Document document = createDocument();
67          final Element element = document.createElement( "foo" );
68  
69          try
70          {
71              deserializer.expectElement( element, "baz" );
72          }
73          catch( Exception e )
74          {
75              final String message =
76                  "Unexpected element. Expected: baz. Actual: foo @ foo.";
77              assertEquals( "e.getMessage()", message, e.getMessage() );
78              return;
79          }
80          fail( "Expected exception as missing element" );
81      }
82  
83      public void testExpectAttributeThatIsPresent()
84          throws Exception
85      {
86          final DOMMetaClassDeserializer deserializer = new DOMMetaClassDeserializer();
87          final Document document = createDocument();
88          final Element element = document.createElement( "foo" );
89          element.setAttribute( "baz", "bar" );
90          final String result = deserializer.expectAttribute( element, "baz" );
91          assertEquals( "result", "bar", result );
92      }
93  
94      public void testExpectAttributeThatIsNotPresent()
95          throws Exception
96      {
97          final DOMMetaClassDeserializer deserializer = new DOMMetaClassDeserializer();
98          final Document document = createDocument();
99          final Element element = document.createElement( "foo" );
100         try
101         {
102             deserializer.expectAttribute( element, "baz" );
103         }
104         catch( Exception e )
105         {
106             final String message =
107                 "Element named foo missing attribute named baz @ foo.";
108             assertEquals( "e.getMessage()", message, e.getMessage() );
109             return;
110         }
111         fail( "Expected exception as missing attribute" );
112     }
113 
114     public void testBuildParam()
115         throws Exception
116     {
117         final DOMMetaClassDeserializer deserializer = new DOMMetaClassDeserializer();
118         final Document document = createDocument();
119         final Element element = document.createElement(
120             MetaClassIOXml.PARAM_ELEMENT );
121         element.setAttribute( MetaClassIOXml.NAME_ATTRIBUTE, "myKey" );
122         element.setAttribute( MetaClassIOXml.VALUE_ATTRIBUTE, "myValue" );
123         final Properties parameters = new Properties();
124         deserializer.buildParam( element, parameters );
125         assertEquals( "parameters.size()", 1, parameters.size() );
126         assertEquals( "parameters['myKey']",
127                       "myValue",
128                       parameters.getProperty( "myKey" ) );
129     }
130 
131     public void testAttributeWithJustName()
132         throws Exception
133     {
134         final DOMMetaClassDeserializer deserializer = new DOMMetaClassDeserializer();
135         final Document document = createDocument();
136         final Element root = document.createElement(
137             MetaClassIOXml.ATTRIBUTES_ELEMENT );
138         final Comment comment1 =
139             document.createComment(
140                 "This comment brought to you by Comments-R-Us" );
141         root.appendChild( comment1 );
142         final Element element = document.createElement(
143             MetaClassIOXml.ATTRIBUTE_ELEMENT );
144         root.appendChild( element );
145         element.setAttribute( MetaClassIOXml.NAME_ATTRIBUTE, "myAttribute" );
146         final Attribute[] attributes = deserializer.buildAttributes( root );
147         assertEquals( "attributes.length", 1, attributes.length );
148         assertEquals( "attributes[0].name",
149                       "myAttribute",
150                       attributes[ 0 ].getName() );
151         assertEquals( "attributes[0].value",
152                       null,
153                       attributes[ 0 ].getValue() );
154         assertEquals( "attributes[0].parameterCount",
155                       0,
156                       attributes[ 0 ].getParameterCount() );
157     }
158 
159     public void testAttributeWithParametersAndValue()
160         throws Exception
161     {
162         final DOMMetaClassDeserializer deserializer = new DOMMetaClassDeserializer();
163         final Document document = createDocument();
164         final Element root = document.createElement(
165             MetaClassIOXml.ATTRIBUTES_ELEMENT );
166         final Comment comment1 =
167             document.createComment(
168                 "This comment brought to you by Comments-R-Us" );
169         root.appendChild( comment1 );
170         final Element element = document.createElement(
171             MetaClassIOXml.ATTRIBUTE_ELEMENT );
172         root.appendChild( element );
173         element.setAttribute( MetaClassIOXml.NAME_ATTRIBUTE, "myAttribute" );
174         final Element parameterElement = document.createElement(
175             MetaClassIOXml.PARAM_ELEMENT );
176         element.appendChild( parameterElement );
177         parameterElement.setAttribute( MetaClassIOXml.NAME_ATTRIBUTE,
178                                        "myKey" );
179         parameterElement.setAttribute( MetaClassIOXml.VALUE_ATTRIBUTE,
180                                        "myValue" );
181 
182         final Text text = document.createTextNode( "Part1" );
183         element.appendChild( text );
184         final Comment comment = document.createComment( "Random COmment" );
185         element.appendChild( comment );
186         final Text text2 = document.createCDATASection( "Part2" );
187         element.appendChild( text2 );
188 
189         try
190         {
191             deserializer.buildAttributes( root );
192         }
193         catch( Exception e )
194         {
195             final Properties parameters = new Properties();
196             parameters.setProperty( "myKey", "myValue" );
197             final String message =
198                 "Attribute named myAttribute specified both a value " +
199                 "(Part1Part2) and parameters (" + parameters + ").";
200             assertEquals( "e.getMessage()", message, e.getMessage() );
201             return;
202         }
203         fail( "Expected to fail due to mixed content" );
204     }
205 
206     public void testAttributeWithParameters()
207         throws Exception
208     {
209         final DOMMetaClassDeserializer deserializer = new DOMMetaClassDeserializer();
210         final Document document = createDocument();
211         final Element root = document.createElement(
212             MetaClassIOXml.ATTRIBUTES_ELEMENT );
213         final Comment comment1 =
214             document.createComment(
215                 "This comment brought to you by Comments-R-Us" );
216         root.appendChild( comment1 );
217         final Element element = document.createElement(
218             MetaClassIOXml.ATTRIBUTE_ELEMENT );
219         root.appendChild( element );
220         element.setAttribute( MetaClassIOXml.NAME_ATTRIBUTE, "myAttribute" );
221         final Element parameterElement = document.createElement(
222             MetaClassIOXml.PARAM_ELEMENT );
223         element.appendChild( parameterElement );
224         parameterElement.setAttribute( MetaClassIOXml.NAME_ATTRIBUTE,
225                                        "myKey" );
226         parameterElement.setAttribute( MetaClassIOXml.VALUE_ATTRIBUTE,
227                                        "myValue" );
228 
229         final Attribute[] attributes = deserializer.buildAttributes( root );
230         assertEquals( "attributes.length", 1, attributes.length );
231         assertEquals( "attributes[0].name",
232                       "myAttribute",
233                       attributes[ 0 ].getName() );
234         assertEquals( "attributes[0].value",
235                       null,
236                       attributes[ 0 ].getValue() );
237         assertEquals( "attributes[0].parameterCount",
238                       1,
239                       attributes[ 0 ].getParameterCount() );
240         assertEquals( "attributes[0].parameters['myKey']",
241                       "myValue",
242                       attributes[ 0 ].getParameter( "myKey" ) );
243     }
244 
245     public void testAttributeWithValue()
246         throws Exception
247     {
248         final DOMMetaClassDeserializer deserializer = new DOMMetaClassDeserializer();
249         final Document document = createDocument();
250         final Element root = document.createElement(
251             MetaClassIOXml.ATTRIBUTES_ELEMENT );
252         final Comment comment1 =
253             document.createComment(
254                 "This comment brought to you by Comments-R-Us" );
255         root.appendChild( comment1 );
256         final Element element = document.createElement(
257             MetaClassIOXml.ATTRIBUTE_ELEMENT );
258         root.appendChild( element );
259         final Text text = document.createTextNode( "Part1" );
260         element.appendChild( text );
261         final Comment comment = document.createComment( "Random COmment" );
262         element.appendChild( comment );
263         final Text text2 = document.createCDATASection( "Part2" );
264         element.appendChild( text2 );
265         element.setAttribute( MetaClassIOXml.NAME_ATTRIBUTE, "myAttribute" );
266         final Attribute[] attributes = deserializer.buildAttributes( root );
267         assertEquals( "attributes.length", 1, attributes.length );
268         assertEquals( "attributes[0].name",
269                       "myAttribute",
270                       attributes[ 0 ].getName() );
271         assertEquals( "attributes[0].value",
272                       "Part1Part2",
273                       attributes[ 0 ].getValue() );
274         assertEquals( "attributes[0].parameterCount",
275                       0,
276                       attributes[ 0 ].getParameterCount() );
277     }
278 
279     public void testBuildField()
280         throws Exception
281     {
282         final DOMMetaClassDeserializer deserializer = new DOMMetaClassDeserializer();
283         final Document document = createDocument();
284         final Element root = document.createElement(
285             MetaClassIOXml.FIELDS_ELEMENT );
286         final Comment comment1 =
287             document.createComment(
288                 "This comment3 brought to you by Comments-R-Us" );
289         root.appendChild( comment1 );
290         final Element element = document.createElement(
291             MetaClassIOXml.FIELD_ELEMENT );
292         root.appendChild( element );
293         element.setAttribute( MetaClassIOXml.NAME_ATTRIBUTE, "myField" );
294         element.setAttribute( MetaClassIOXml.TYPE_ATTRIBUTE, "int" );
295         final Comment comment2 = document.createComment( "Random COmment" );
296         element.appendChild( comment2 );
297 
298         final Element attributes = document.createElement(
299             MetaClassIOXml.ATTRIBUTES_ELEMENT );
300         element.appendChild( attributes );
301         final Element attribute = document.createElement(
302             MetaClassIOXml.ATTRIBUTE_ELEMENT );
303         attributes.appendChild( attribute );
304         final Comment comment = document.createComment( "Random COmment" );
305         attributes.appendChild( comment );
306         attribute.setAttribute( MetaClassIOXml.NAME_ATTRIBUTE, "myAttribute" );
307         final Comment comment3 = document.createComment( "Random COmment" );
308         attribute.appendChild( comment3 );
309 
310         final FieldDescriptor[] fields = deserializer.buildFields( root );
311         assertEquals( "fields.length", 1, fields.length );
312         assertEquals( "fields[0].name", "myField", fields[ 0 ].getName() );
313         assertEquals( "fields[0].type", "int", fields[ 0 ].getType() );
314         assertEquals( "fields[0].attributeCount",
315                       1,
316                       fields[ 0 ].getAttributes().length );
317     }
318 
319     public void testBuildParameter()
320         throws Exception
321     {
322         final DOMMetaClassDeserializer deserializer = new DOMMetaClassDeserializer();
323         final Document document = createDocument();
324         final Element root = document.createElement(
325             MetaClassIOXml.PARAMETERS_ELEMENT );
326         final Comment comment1 =
327             document.createComment(
328                 "This comment brought to you by Comments-R-Us" );
329         root.appendChild( comment1 );
330         final Element element = document.createElement(
331             MetaClassIOXml.PARAMETER_ELEMENT );
332         root.appendChild( element );
333         element.setAttribute( MetaClassIOXml.NAME_ATTRIBUTE, "myParam" );
334         element.setAttribute( MetaClassIOXml.TYPE_ATTRIBUTE, "int" );
335         final ParameterDescriptor[] parameters = deserializer.buildParameters(
336             root );
337         assertEquals( "parameters.length", 1, parameters.length );
338         assertEquals( "parameters[0].name",
339                       "myParam",
340                       parameters[ 0 ].getName() );
341         assertEquals( "parameters[0].type", "int", parameters[ 0 ].getType() );
342     }
343 
344     public void testBuildMethod()
345         throws Exception
346     {
347         final DOMMetaClassDeserializer deserializer = new DOMMetaClassDeserializer();
348         final Document document = createDocument();
349         final Element root = document.createElement(
350             MetaClassIOXml.METHODS_ELEMENT );
351         final Comment comment1 =
352             document.createComment(
353                 "This comment brought to you by Comments-R-Us" );
354         root.appendChild( comment1 );
355 
356         final Element element = document.createElement(
357             MetaClassIOXml.METHOD_ELEMENT );
358         root.appendChild( element );
359         element.setAttribute( MetaClassIOXml.NAME_ATTRIBUTE, "myMethod" );
360         element.setAttribute( MetaClassIOXml.TYPE_ATTRIBUTE, "int" );
361 
362         final Comment comment = document.createComment( "Random COmment" );
363         element.appendChild( comment );
364 
365         final Element parameters = document.createElement(
366             MetaClassIOXml.PARAMETERS_ELEMENT );
367         element.appendChild( parameters );
368         final Element parameter = document.createElement(
369             MetaClassIOXml.PARAMETER_ELEMENT );
370         parameters.appendChild( parameter );
371         parameter.setAttribute( MetaClassIOXml.NAME_ATTRIBUTE, "myParam" );
372         parameter.setAttribute( MetaClassIOXml.TYPE_ATTRIBUTE, "int" );
373 
374         final Element attributes = document.createElement(
375             MetaClassIOXml.ATTRIBUTES_ELEMENT );
376         element.appendChild( attributes );
377 
378         final MethodDescriptor[] methods = deserializer.buildMethods( root );
379         assertEquals( "methods.length", 1, methods.length );
380         assertEquals( "methods[0].name", "myMethod", methods[ 0 ].getName() );
381         assertEquals( "methods[0].returnType",
382                       "int",
383                       methods[ 0 ].getReturnType() );
384         assertEquals( "methods[0].parameters.length",
385                       1,
386                       methods[ 0 ].getParameters().length );
387     }
388 
389     public void testBuildClass()
390         throws Exception
391     {
392         final DOMMetaClassDeserializer deserializer = new DOMMetaClassDeserializer();
393         final Document document = createDocument();
394         final Element root = document.createElement(
395             MetaClassIOXml.CLASS_ELEMENT );
396         document.appendChild( root );
397         root.setAttribute( MetaClassIOXml.TYPE_ATTRIBUTE, "MyClass" );
398 
399         final Comment comment1 =
400             document.createComment(
401                 "This comment brought to you by Comments-R-Us" );
402         root.appendChild( comment1 );
403 
404         final Element methods = document.createElement(
405             MetaClassIOXml.METHODS_ELEMENT );
406         root.appendChild( methods );
407         final Element fields = document.createElement(
408             MetaClassIOXml.FIELDS_ELEMENT );
409         root.appendChild( fields );
410         final Element attributes = document.createElement(
411             MetaClassIOXml.ATTRIBUTES_ELEMENT );
412         root.appendChild( attributes );
413 
414         final ClassDescriptor clazz = deserializer.buildClassDescriptor(
415             document );
416         assertEquals( "clazz.length", "MyClass", clazz.getName() );
417         assertEquals( "clazz.fields.length", 0, clazz.getFields().length );
418         assertEquals( "clazz.methods.length", 0, clazz.getMethods().length );
419         assertEquals( "clazz.attributes.length",
420                       0,
421                       clazz.getAttributes().length );
422     }
423 
424     private Document createDocument()
425         throws Exception
426     {
427         final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
428         final DocumentBuilder builder = factory.newDocumentBuilder();
429         return builder.newDocument();
430     }
431 }