|
|||||||||||||||||||
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover | |||||||||||||||||||
Source file | Conditionals | Statements | Methods | TOTAL | |||||||||||||||
DOMMetaClassDeserializer.java | 100% | 100% | 100% | 100% |
|
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.ArrayList;
|
|
11 |
import java.util.Properties;
|
|
12 |
import org.codehaus.metaclass.model.Attribute;
|
|
13 |
import org.codehaus.metaclass.model.ClassDescriptor;
|
|
14 |
import org.codehaus.metaclass.model.FieldDescriptor;
|
|
15 |
import org.codehaus.metaclass.model.MethodDescriptor;
|
|
16 |
import org.codehaus.metaclass.model.ParameterDescriptor;
|
|
17 |
import org.w3c.dom.Element;
|
|
18 |
import org.w3c.dom.Node;
|
|
19 |
import org.w3c.dom.NodeList;
|
|
20 |
import org.w3c.dom.Attr;
|
|
21 |
import org.w3c.dom.Document;
|
|
22 |
|
|
23 |
/**
|
|
24 |
* Utility class to build a ClassDescriptor from a DOM
|
|
25 |
* representation Element.
|
|
26 |
*
|
|
27 |
* @author Peter Donald
|
|
28 |
* @version $Revision: 1.13 $ $Date: 2003/11/27 08:09:53 $
|
|
29 |
*/
|
|
30 |
public final class DOMMetaClassDeserializer |
|
31 |
{ |
|
32 |
/**
|
|
33 |
* Build a ClassDescriptor from a Document.
|
|
34 |
*
|
|
35 |
* @param document the document
|
|
36 |
* @return the ClassDescriptor
|
|
37 |
* @throws Exception if document malformed
|
|
38 |
*/
|
|
39 | 6 |
public ClassDescriptor buildClassDescriptor( final Document document )
|
40 |
throws Exception
|
|
41 |
{ |
|
42 | 6 |
return buildClassDescriptor( document.getDocumentElement() );
|
43 |
} |
|
44 |
|
|
45 |
/**
|
|
46 |
* Build a ClassDescriptor from element.
|
|
47 |
*
|
|
48 |
* @param element the element
|
|
49 |
* @return the ClassDescriptor
|
|
50 |
* @throws Exception if element malformed
|
|
51 |
*/
|
|
52 | 6 |
public ClassDescriptor buildClassDescriptor( final Element element )
|
53 |
throws Exception
|
|
54 |
{ |
|
55 | 6 |
expectElement( element, MetaClassIOXml.CLASS_ELEMENT ); |
56 | 6 |
final String type = |
57 |
expectAttribute( element, MetaClassIOXml.TYPE_ATTRIBUTE ); |
|
58 | 6 |
Attribute[] attributes = Attribute.EMPTY_SET; |
59 | 6 |
MethodDescriptor[] methods = MethodDescriptor.EMPTY_SET; |
60 | 6 |
FieldDescriptor[] fields = FieldDescriptor.EMPTY_SET; |
61 | 6 |
final NodeList nodes = element.getChildNodes(); |
62 | 6 |
final int length = nodes.getLength();
|
63 | 6 |
for( int i = 0; i < length; i++ ) |
64 |
{ |
|
65 | 14 |
final Node node = nodes.item( i ); |
66 | 14 |
final short nodeType = node.getNodeType();
|
67 | 14 |
if( nodeType == Node.ELEMENT_NODE )
|
68 |
{ |
|
69 | 8 |
final Element child = (Element)node; |
70 | 8 |
final String childName = child.getNodeName(); |
71 | 8 |
if( childName.equals( MetaClassIOXml.METHODS_ELEMENT ) )
|
72 |
{ |
|
73 | 2 |
methods = buildMethods( child ); |
74 |
} |
|
75 | 6 |
else if( childName.equals( MetaClassIOXml.FIELDS_ELEMENT ) ) |
76 |
{ |
|
77 | 2 |
fields = buildFields( child ); |
78 |
} |
|
79 |
else
|
|
80 |
{ |
|
81 | 4 |
attributes = buildAttributes( child ); |
82 |
} |
|
83 |
} |
|
84 |
} |
|
85 | 6 |
return new ClassDescriptor( type, |
86 |
attributes, |
|
87 |
attributes, |
|
88 |
fields, |
|
89 |
methods ); |
|
90 |
} |
|
91 |
|
|
92 |
/**
|
|
93 |
* Build a set of methods from element.
|
|
94 |
*
|
|
95 |
* @param element the element
|
|
96 |
* @return the methods
|
|
97 |
* @throws Exception if element malformed
|
|
98 |
*/
|
|
99 | 4 |
MethodDescriptor[] buildMethods( final Element element ) |
100 |
throws Exception
|
|
101 |
{ |
|
102 | 4 |
expectElement( element, MetaClassIOXml.METHODS_ELEMENT ); |
103 |
|
|
104 | 4 |
final ArrayList methods = new ArrayList();
|
105 | 4 |
final NodeList nodes = element.getChildNodes(); |
106 | 4 |
final int length = nodes.getLength();
|
107 | 4 |
for( int i = 0; i < length; i++ ) |
108 |
{ |
|
109 | 4 |
final Node node = nodes.item( i ); |
110 | 4 |
final short nodeType = node.getNodeType();
|
111 | 4 |
if( nodeType == Node.ELEMENT_NODE )
|
112 |
{ |
|
113 | 2 |
final MethodDescriptor field = buildMethod( (Element)node ); |
114 | 2 |
methods.add( field ); |
115 |
} |
|
116 |
} |
|
117 |
|
|
118 | 4 |
return (MethodDescriptor[])methods.
|
119 |
toArray( new MethodDescriptor[ methods.size() ] );
|
|
120 |
} |
|
121 |
|
|
122 |
/**
|
|
123 |
* Build a method from element.
|
|
124 |
*
|
|
125 |
* @param element the element
|
|
126 |
* @return the method
|
|
127 |
* @throws Exception if element malformed
|
|
128 |
*/
|
|
129 | 2 |
MethodDescriptor buildMethod( final Element element ) |
130 |
throws Exception
|
|
131 |
{ |
|
132 | 2 |
expectElement( element, MetaClassIOXml.METHOD_ELEMENT ); |
133 | 2 |
final String name = |
134 |
expectAttribute( element, MetaClassIOXml.NAME_ATTRIBUTE ); |
|
135 | 2 |
final String type = |
136 |
expectAttribute( element, MetaClassIOXml.TYPE_ATTRIBUTE ); |
|
137 | 2 |
Attribute[] attributes = Attribute.EMPTY_SET; |
138 | 2 |
ParameterDescriptor[] parameters = ParameterDescriptor.EMPTY_SET; |
139 | 2 |
final NodeList nodes = element.getChildNodes(); |
140 | 2 |
final int length = nodes.getLength();
|
141 | 2 |
for( int i = 0; i < length; i++ ) |
142 |
{ |
|
143 | 6 |
final Node node = nodes.item( i ); |
144 | 6 |
final short nodeType = node.getNodeType();
|
145 | 6 |
if( nodeType == Node.ELEMENT_NODE )
|
146 |
{ |
|
147 | 4 |
final Element child = (Element)node; |
148 | 4 |
final String childName = child.getNodeName(); |
149 | 4 |
if( childName.equals( MetaClassIOXml.PARAMETERS_ELEMENT ) )
|
150 |
{ |
|
151 | 2 |
parameters = buildParameters( child ); |
152 |
} |
|
153 |
else
|
|
154 |
{ |
|
155 | 2 |
attributes = buildAttributes( child ); |
156 |
} |
|
157 |
} |
|
158 |
} |
|
159 | 2 |
return new MethodDescriptor( name, type, parameters, attributes, attributes ); |
160 |
} |
|
161 |
|
|
162 |
/**
|
|
163 |
* Build a set of method parameters from element.
|
|
164 |
*
|
|
165 |
* @param element the element
|
|
166 |
* @return the method parameters
|
|
167 |
* @throws Exception if element malformed
|
|
168 |
*/
|
|
169 | 4 |
ParameterDescriptor[] buildParameters( final Element element ) |
170 |
throws Exception
|
|
171 |
{ |
|
172 | 4 |
expectElement( element, MetaClassIOXml.PARAMETERS_ELEMENT ); |
173 |
|
|
174 | 4 |
final ArrayList parameters = new ArrayList();
|
175 | 4 |
final NodeList nodes = element.getChildNodes(); |
176 | 4 |
final int length = nodes.getLength();
|
177 | 4 |
for( int i = 0; i < length; i++ ) |
178 |
{ |
|
179 | 6 |
final Node node = nodes.item( i ); |
180 | 6 |
final short nodeType = node.getNodeType();
|
181 | 6 |
if( nodeType == Node.ELEMENT_NODE )
|
182 |
{ |
|
183 | 4 |
final ParameterDescriptor parameter = |
184 |
buildParameter( (Element)node ); |
|
185 | 4 |
parameters.add( parameter ); |
186 |
} |
|
187 |
} |
|
188 |
|
|
189 | 4 |
return (ParameterDescriptor[])parameters.
|
190 |
toArray( new ParameterDescriptor[ parameters.size() ] );
|
|
191 |
} |
|
192 |
|
|
193 |
/**
|
|
194 |
* Build a method parameter from element.
|
|
195 |
*
|
|
196 |
* @param element the element
|
|
197 |
* @return the method parameter
|
|
198 |
* @throws Exception if element malformed
|
|
199 |
*/
|
|
200 | 4 |
ParameterDescriptor buildParameter( final Element element ) |
201 |
throws Exception
|
|
202 |
{ |
|
203 | 4 |
expectElement( element, MetaClassIOXml.PARAMETER_ELEMENT ); |
204 | 4 |
final String name = |
205 |
expectAttribute( element, MetaClassIOXml.NAME_ATTRIBUTE ); |
|
206 | 4 |
final String type = |
207 |
expectAttribute( element, MetaClassIOXml.TYPE_ATTRIBUTE ); |
|
208 |
|
|
209 | 4 |
return new ParameterDescriptor( name, type ); |
210 |
} |
|
211 |
|
|
212 |
/**
|
|
213 |
* Build a set of fields from element.
|
|
214 |
*
|
|
215 |
* @param element the element
|
|
216 |
* @return the fields
|
|
217 |
* @throws Exception if element malformed
|
|
218 |
*/
|
|
219 | 4 |
FieldDescriptor[] buildFields( final Element element ) |
220 |
throws Exception
|
|
221 |
{ |
|
222 | 4 |
expectElement( element, MetaClassIOXml.FIELDS_ELEMENT ); |
223 |
|
|
224 | 4 |
final ArrayList fields = new ArrayList();
|
225 | 4 |
final NodeList nodes = element.getChildNodes(); |
226 | 4 |
final int length = nodes.getLength();
|
227 | 4 |
for( int i = 0; i < length; i++ ) |
228 |
{ |
|
229 | 4 |
final Node node = nodes.item( i ); |
230 | 4 |
final short nodeType = node.getNodeType();
|
231 | 4 |
if( nodeType == Node.ELEMENT_NODE )
|
232 |
{ |
|
233 | 2 |
final FieldDescriptor field = buildField( (Element)node ); |
234 | 2 |
fields.add( field ); |
235 |
} |
|
236 |
} |
|
237 |
|
|
238 | 4 |
return (FieldDescriptor[])fields.
|
239 |
toArray( new FieldDescriptor[ fields.size() ] );
|
|
240 |
} |
|
241 |
|
|
242 |
/**
|
|
243 |
* Build a field from element.
|
|
244 |
*
|
|
245 |
* @param element the element
|
|
246 |
* @return the field
|
|
247 |
* @throws Exception if element malformed
|
|
248 |
*/
|
|
249 | 2 |
FieldDescriptor buildField( final Element element ) |
250 |
throws Exception
|
|
251 |
{ |
|
252 | 2 |
expectElement( element, MetaClassIOXml.FIELD_ELEMENT ); |
253 | 2 |
final String name = |
254 |
expectAttribute( element, MetaClassIOXml.NAME_ATTRIBUTE ); |
|
255 | 2 |
final String type = |
256 |
expectAttribute( element, MetaClassIOXml.TYPE_ATTRIBUTE ); |
|
257 | 2 |
Attribute[] attributes = Attribute.EMPTY_SET; |
258 | 2 |
final NodeList nodes = element.getChildNodes(); |
259 | 2 |
final int length = nodes.getLength();
|
260 | 2 |
for( int i = 0; i < length; i++ ) |
261 |
{ |
|
262 | 4 |
final Node node = nodes.item( i ); |
263 | 4 |
final short nodeType = node.getNodeType();
|
264 | 4 |
if( nodeType == Node.ELEMENT_NODE )
|
265 |
{ |
|
266 | 2 |
attributes = buildAttributes( (Element)node ); |
267 |
} |
|
268 |
} |
|
269 | 2 |
return new FieldDescriptor( name, type, attributes, attributes ); |
270 |
} |
|
271 |
|
|
272 |
/**
|
|
273 |
* Build a set of attributes from element.
|
|
274 |
*
|
|
275 |
* @param element the element
|
|
276 |
* @return the attributes
|
|
277 |
* @throws Exception if element malformed
|
|
278 |
*/
|
|
279 | 16 |
Attribute[] buildAttributes( final Element element ) |
280 |
throws Exception
|
|
281 |
{ |
|
282 | 16 |
expectElement( element, MetaClassIOXml.ATTRIBUTES_ELEMENT ); |
283 |
|
|
284 | 16 |
final ArrayList attributes = new ArrayList();
|
285 | 16 |
final NodeList nodes = element.getChildNodes(); |
286 | 16 |
final int length = nodes.getLength();
|
287 | 16 |
for( int i = 0; i < length; i++ ) |
288 |
{ |
|
289 | 26 |
final Node node = nodes.item( i ); |
290 | 26 |
final short nodeType = node.getNodeType();
|
291 | 26 |
if( nodeType == Node.ELEMENT_NODE )
|
292 |
{ |
|
293 | 12 |
final Attribute attribute = buildAttribute( (Element)node ); |
294 | 10 |
attributes.add( attribute ); |
295 |
} |
|
296 |
} |
|
297 |
|
|
298 | 14 |
return (Attribute[])attributes.
|
299 |
toArray( new Attribute[ attributes.size() ] );
|
|
300 |
} |
|
301 |
|
|
302 |
/**
|
|
303 |
* Build attribute from specified element.
|
|
304 |
*
|
|
305 |
* @param element the element
|
|
306 |
* @return the attribute
|
|
307 |
* @throws Exception if element malformed
|
|
308 |
*/
|
|
309 | 12 |
Attribute buildAttribute( final Element element ) |
310 |
throws Exception
|
|
311 |
{ |
|
312 | 12 |
expectElement( element, MetaClassIOXml.ATTRIBUTE_ELEMENT ); |
313 | 12 |
final String name = |
314 |
expectAttribute( element, MetaClassIOXml.NAME_ATTRIBUTE ); |
|
315 |
|
|
316 | 12 |
final StringBuffer sb = new StringBuffer();
|
317 | 12 |
final Properties parameters = new Properties();
|
318 | 12 |
final NodeList nodes = element.getChildNodes(); |
319 | 12 |
final int length = nodes.getLength();
|
320 | 12 |
for( int i = 0; i < length; i++ ) |
321 |
{ |
|
322 | 18 |
final Node node = nodes.item( i ); |
323 | 18 |
final short nodeType = node.getNodeType();
|
324 | 18 |
if( nodeType == Node.ELEMENT_NODE )
|
325 |
{ |
|
326 | 4 |
buildParam( (Element)node, parameters ); |
327 |
} |
|
328 | 14 |
else if( nodeType == Node.TEXT_NODE || |
329 |
nodeType == Node.CDATA_SECTION_NODE ) |
|
330 |
{ |
|
331 | 8 |
final String value = node.getNodeValue(); |
332 | 8 |
sb.append( value ); |
333 |
} |
|
334 |
} |
|
335 |
|
|
336 | 12 |
final String value = sb.toString().trim(); |
337 | 12 |
if( 0 != value.length() &&
|
338 |
0 < parameters.size() ) |
|
339 |
{ |
|
340 | 2 |
final String message = |
341 |
"Attribute named " + name +
|
|
342 |
" specified both a value (" + value + ") " + |
|
343 |
"and parameters (" + parameters + ")."; |
|
344 | 2 |
throw new Exception( message ); |
345 |
} |
|
346 | 10 |
if( 0 == value.length() )
|
347 |
{ |
|
348 | 8 |
return new Attribute( name, parameters ); |
349 |
} |
|
350 |
else
|
|
351 |
{ |
|
352 | 2 |
return new Attribute( name, value ); |
353 |
} |
|
354 |
} |
|
355 |
|
|
356 |
/**
|
|
357 |
* Build a parameter from element and add to specified parameters.
|
|
358 |
*
|
|
359 |
* @param element the element
|
|
360 |
* @param parameters the parameters
|
|
361 |
* @throws Exception if element malformed
|
|
362 |
*/
|
|
363 | 6 |
void buildParam( final Element element,
|
364 |
final Properties parameters ) |
|
365 |
throws Exception
|
|
366 |
{ |
|
367 | 6 |
expectElement( element, MetaClassIOXml.PARAM_ELEMENT ); |
368 | 6 |
final String name = |
369 |
expectAttribute( element, MetaClassIOXml.NAME_ATTRIBUTE ); |
|
370 | 6 |
final String value = |
371 |
expectAttribute( element, MetaClassIOXml.VALUE_ATTRIBUTE ); |
|
372 | 6 |
parameters.setProperty( name, value ); |
373 |
} |
|
374 |
|
|
375 |
/**
|
|
376 |
* Expect that specified element has specified name else
|
|
377 |
* throw an exception.
|
|
378 |
*
|
|
379 |
* @param element the element
|
|
380 |
* @param name the name
|
|
381 |
* @throws Exception if element does not have name
|
|
382 |
*/
|
|
383 | 64 |
void expectElement( final Element element,
|
384 |
final String name ) |
|
385 |
throws Exception
|
|
386 |
{ |
|
387 | 64 |
final String actual = element.getTagName(); |
388 | 64 |
if( !actual.equals( name ) )
|
389 |
{ |
|
390 | 2 |
final String message = "Unexpected element. " +
|
391 |
"Expected: " + name + ". Actual: " + actual + |
|
392 |
" @ " + getPathDescription( element ) + "."; |
|
393 | 2 |
throw new Exception( message ); |
394 |
} |
|
395 |
} |
|
396 |
|
|
397 |
/**
|
|
398 |
* Expect that specified element has attribute with specified
|
|
399 |
* name and return value. If attribute can not be located then
|
|
400 |
* throw an exception.
|
|
401 |
*
|
|
402 |
* @param element the element
|
|
403 |
* @param name the attributes name
|
|
404 |
* @return the attributes value
|
|
405 |
* @throws Exception if unable to locate attribute
|
|
406 |
*/
|
|
407 | 50 |
String expectAttribute( final Element element, |
408 |
final String name ) |
|
409 |
throws Exception
|
|
410 |
{ |
|
411 | 50 |
final Attr actual = element.getAttributeNode( name ); |
412 | 50 |
if( null == actual ) |
413 |
{ |
|
414 | 2 |
final String message = |
415 |
"Element named " + element.getTagName() +
|
|
416 |
" missing attribute named " + name +
|
|
417 |
" @ " + getPathDescription( element ) + "."; |
|
418 | 2 |
throw new Exception( message ); |
419 |
} |
|
420 | 48 |
return actual.getValue();
|
421 |
} |
|
422 |
|
|
423 |
/**
|
|
424 |
* Return a description of path to specified element.
|
|
425 |
* The path is separate by "/" and starts with root
|
|
426 |
* element descending to specified element.
|
|
427 |
*
|
|
428 |
* @param cause the element
|
|
429 |
* @return the path description
|
|
430 |
*/
|
|
431 | 8 |
String getPathDescription( final Element cause ) |
432 |
{ |
|
433 | 8 |
final StringBuffer sb = new StringBuffer();
|
434 |
|
|
435 | 8 |
Element element = cause; |
436 | 8 |
while( true ) |
437 |
{ |
|
438 | 10 |
if( sb.length() > 0 )
|
439 |
{ |
|
440 | 2 |
sb.insert( 0, "/" );
|
441 |
} |
|
442 | 10 |
sb.insert( 0, element.getNodeName() ); |
443 | 10 |
final Node parentNode = element.getParentNode(); |
444 | 10 |
if( parentNode instanceof Element ) |
445 |
{ |
|
446 | 2 |
element = (Element)parentNode; |
447 |
} |
|
448 |
else
|
|
449 |
{ |
|
450 | 8 |
break;
|
451 |
} |
|
452 |
} |
|
453 |
|
|
454 | 8 |
return sb.toString();
|
455 |
} |
|
456 |
} |
|
457 |
|
|