Clover coverage report - MetaClass - 1.1
Coverage timestamp: Tue Apr 27 2004 10:46:24 EST
file stats: LOC: 457   Methods: 14
NCLOC: 311   Classes: 1
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%
coverage
 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