Clover coverage report - MetaClass - 1.1
Coverage timestamp: Tue Apr 27 2004 10:46:24 EST
file stats: LOC: 448   Methods: 14
NCLOC: 275   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
QDoxDescriptorParser.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.tools.qdox;
 9   
 
 10   
 import com.thoughtworks.qdox.model.DocletTag;
 11   
 import com.thoughtworks.qdox.model.JavaClass;
 12   
 import com.thoughtworks.qdox.model.JavaField;
 13   
 import com.thoughtworks.qdox.model.JavaMethod;
 14   
 import com.thoughtworks.qdox.model.JavaParameter;
 15   
 import com.thoughtworks.qdox.model.Type;
 16   
 import java.util.ArrayList;
 17   
 import java.util.Properties;
 18   
 import org.codehaus.metaclass.model.Attribute;
 19   
 import org.codehaus.metaclass.model.ClassDescriptor;
 20   
 import org.codehaus.metaclass.model.FieldDescriptor;
 21   
 import org.codehaus.metaclass.model.MethodDescriptor;
 22   
 import org.codehaus.metaclass.model.ParameterDescriptor;
 23   
 
 24   
 /**
 25   
  * This class is responsible for parsing a JavaClass object
 26   
  * and building a ClassDescriptor to correspond to the JavaClass
 27   
  * object.
 28   
  *
 29   
  * @version $Revision: 1.20 $ $Date: 2003/10/28 13:40:52 $
 30   
  */
 31   
 public class QDoxDescriptorParser
 32   
 {
 33   
     /**
 34   
      * Constant indicating parse state is
 35   
      * before the start of key.
 36   
      */
 37   
     private static final int PARSE_KEY_START = 0;
 38   
 
 39   
     /**
 40   
      * Constant indicating parse state is
 41   
      * parsing the key.
 42   
      */
 43   
     private static final int PARSE_KEY = 1;
 44   
 
 45   
     /**
 46   
      * Constant indicating parse state is
 47   
      * before the start of value and expecting ".
 48   
      */
 49   
     private static final int PARSE_VALUE_START = 2;
 50   
 
 51   
     /**
 52   
      * Constant indicating parse state is
 53   
      * parsing value string.
 54   
      */
 55   
     private static final int PARSE_VALUE = 3;
 56   
 
 57   
     /**
 58   
      * Constant indicating parse state is
 59   
      * after value closed.
 60   
      */
 61   
     private static final int PARSE_END = 4;
 62   
 
 63   
     /**
 64   
      * Build a ClassDescriptor for a JavaClass.
 65   
      *
 66   
      * @param javaClass the JavaClass
 67   
      * @return the ClassDescriptor
 68   
      */
 69  2
     public ClassDescriptor buildClassDescriptor( final JavaClass javaClass )
 70   
     {
 71  2
         return buildClassDescriptor( javaClass, new DefaultQDoxAttributeInterceptor() );
 72   
     }
 73   
 
 74   
     /**
 75   
      * Build a ClassDescriptor for a JavaClass.
 76   
      *
 77   
      * @param javaClass the JavaClass
 78   
      * @param interceptors the AttributeInterceptors
 79   
      * @return the ClassDescriptor
 80   
      */
 81  28
     public ClassDescriptor buildClassDescriptor( final JavaClass javaClass,
 82   
                                                  final QDoxAttributeInterceptor[] interceptors )
 83   
     {
 84  28
         return buildClassDescriptor( javaClass, new MulticastInterceptor( interceptors ) );
 85   
     }
 86   
 
 87   
     /**
 88   
      * Build a ClassDescriptor for a JavaClass.
 89   
      *
 90   
      * @param javaClass the JavaClass
 91   
      * @param interceptor the AttributeInterceptor
 92   
      * @return the ClassDescriptor
 93   
      */
 94  38
     public ClassDescriptor buildClassDescriptor( final JavaClass javaClass,
 95   
                                                  final QDoxAttributeInterceptor interceptor )
 96   
     {
 97  38
         final String classname = javaClass.getFullyQualifiedName();
 98  38
         final Attribute[] originalAttributes = buildAttributes( javaClass, interceptor );
 99  36
         final Attribute[] attributes =
 100   
             interceptor.processClassAttributes( javaClass, originalAttributes );
 101   
 
 102  36
         final FieldDescriptor[] fields =
 103   
             buildFields( javaClass.getFields(), interceptor );
 104  36
         final MethodDescriptor[] methods =
 105   
             buildMethods( javaClass.getMethods(), interceptor );
 106   
 
 107  36
         return new ClassDescriptor( classname,
 108   
                                     attributes,
 109   
                                     attributes,
 110   
                                     fields,
 111   
                                     methods );
 112   
     }
 113   
 
 114   
     /**
 115   
      * Build a set of MethodDescriptor instances for a JavaClass.
 116   
      *
 117   
      * @param methods the methods
 118   
      * @param interceptor the AttributeInterceptor
 119   
      * @return the MethodDescriptors
 120   
      */
 121  38
     MethodDescriptor[] buildMethods( final JavaMethod[] methods,
 122   
                                      final QDoxAttributeInterceptor interceptor )
 123   
     {
 124  38
         final MethodDescriptor[] methodDescriptors = new MethodDescriptor[ methods.length ];
 125  38
         for( int i = 0; i < methods.length; i++ )
 126   
         {
 127  2
             methodDescriptors[ i ] = buildMethod( methods[ i ], interceptor );
 128   
         }
 129  38
         return methodDescriptors;
 130   
     }
 131   
 
 132   
     /**
 133   
      * Build a MethodDescriptor for a JavaMethod.
 134   
      *
 135   
      * @param method the JavaMethod
 136   
      * @param interceptor the AttributeInterceptor
 137   
      * @return the MethodDescriptor
 138   
      */
 139  12
     MethodDescriptor buildMethod( final JavaMethod method,
 140   
                                   final QDoxAttributeInterceptor interceptor )
 141   
     {
 142  12
         final String name = method.getName();
 143  12
         final Type returns = method.getReturns();
 144  12
         final String type;
 145  12
         if( null != returns )
 146   
         {
 147  10
             type = returns.getValue();
 148   
         }
 149   
         else
 150   
         {
 151  2
             type = "";
 152   
         }
 153   
 
 154  12
         final Attribute[] originalAttributes = buildAttributes( method, interceptor );
 155  12
         final Attribute[] attributes =
 156   
             interceptor.processMethodAttributes( method, originalAttributes );
 157  12
         final ParameterDescriptor[] parameters =
 158   
             buildParameters( method.getParameters() );
 159   
 
 160  12
         return new MethodDescriptor( name,
 161   
                                      type,
 162   
                                      parameters,
 163   
                                      attributes, 
 164   
                                      attributes );
 165   
     }
 166   
 
 167   
     /**
 168   
      * Build a set of ParameterDescriptor for JavaParameters.
 169   
      *
 170   
      * @param parameters the JavaParameters
 171   
      * @return the ParameterDescriptors
 172   
      */
 173  14
     ParameterDescriptor[] buildParameters( final JavaParameter[] parameters )
 174   
     {
 175  14
         final ParameterDescriptor[] descriptors =
 176   
             new ParameterDescriptor[ parameters.length ];
 177  14
         for( int i = 0; i < parameters.length; i++ )
 178   
         {
 179  2
             descriptors[ i ] = buildParameter( parameters[ i ] );
 180   
         }
 181  14
         return descriptors;
 182   
     }
 183   
 
 184   
     /**
 185   
      * Build a ParameterDescriptor for a JavaParameter.
 186   
      *
 187   
      * @param parameter the JavaParameter
 188   
      * @return the ParameterDescriptor
 189   
      */
 190  4
     ParameterDescriptor buildParameter( final JavaParameter parameter )
 191   
     {
 192  4
         final String name = parameter.getName();
 193  4
         final String value = parameter.getType().getValue();
 194  4
         return new ParameterDescriptor( name, value );
 195   
     }
 196   
 
 197   
     /**
 198   
      * Build a set of FieldDescriptor instances for a JavaClass.
 199   
      *
 200   
      * @param fields the fields
 201   
      * @param interceptor the AttributeInterceptor
 202   
      * @return the FieldDescriptors
 203   
      */
 204  38
     FieldDescriptor[] buildFields( final JavaField[] fields,
 205   
                                    final QDoxAttributeInterceptor interceptor )
 206   
     {
 207  38
         final FieldDescriptor[] fieldDescriptors = new FieldDescriptor[ fields.length ];
 208  38
         for( int i = 0; i < fields.length; i++ )
 209   
         {
 210  2
             fieldDescriptors[ i ] = buildField( fields[ i ], interceptor );
 211   
         }
 212  38
         return fieldDescriptors;
 213   
     }
 214   
 
 215   
     /**
 216   
      * Build a set of FieldDescriptor instances for a JavaField.
 217   
      *
 218   
      * @param field the JavaField
 219   
      * @param interceptor the AttributeInterceptor
 220   
      * @return the FieldDescriptor
 221   
      */
 222  10
     FieldDescriptor buildField( final JavaField field,
 223   
                                 final QDoxAttributeInterceptor interceptor )
 224   
     {
 225  10
         final String name = field.getName();
 226  10
         final String type = field.getType().getValue();
 227  10
         final Attribute[] originalAttributes = buildAttributes( field, interceptor );
 228  10
         final Attribute[] attributes =
 229   
             interceptor.processFieldAttributes( field, originalAttributes );
 230  10
         return new FieldDescriptor( name,
 231   
                                     type,
 232   
                                     attributes,
 233   
                                     attributes );
 234   
     }
 235   
 
 236   
     /**
 237   
      * Build a set of Attribute instances for a JavaClass.
 238   
      * Use Interceptor to process tags during construction.
 239   
      *
 240   
      * @param javaClass the JavaClass
 241   
      * @param interceptor the AttributeInterceptor
 242   
      * @return the Attributes
 243   
      */
 244  38
     private Attribute[] buildAttributes( final JavaClass javaClass,
 245   
                                          final QDoxAttributeInterceptor interceptor )
 246   
     {
 247  38
         final ArrayList attributes = new ArrayList();
 248  38
         final DocletTag[] tags = javaClass.getTags();
 249  38
         for( int i = 0; i < tags.length; i++ )
 250   
         {
 251  40
             final Attribute originalAttribute = buildAttribute( tags[ i ] );
 252  40
             final Attribute attribute =
 253   
                 interceptor.processClassAttribute( javaClass, originalAttribute );
 254  38
             if( null != attribute )
 255   
             {
 256  34
                 attributes.add( attribute );
 257   
             }
 258   
         }
 259  36
         return (Attribute[])attributes.toArray( new Attribute[ attributes.size() ] );
 260   
     }
 261   
 
 262   
     /**
 263   
      * Build a set of Attribute instances for a JavaMethod.
 264   
      * Use Interceptor to process tags during construction.
 265   
      *
 266   
      * @param method the JavaMethod
 267   
      * @param interceptor the AttributeInterceptor
 268   
      * @return the Attributes
 269   
      */
 270  12
     private Attribute[] buildAttributes( final JavaMethod method,
 271   
                                          final QDoxAttributeInterceptor interceptor )
 272   
     {
 273  12
         final ArrayList attributes = new ArrayList();
 274  12
         final DocletTag[] tags = method.getTags();
 275  12
         for( int i = 0; i < tags.length; i++ )
 276   
         {
 277  12
             final Attribute originalAttribute = buildAttribute( tags[ i ] );
 278  12
             final Attribute attribute =
 279   
                 interceptor.processMethodAttribute( method, originalAttribute );
 280  12
             if( null != attribute )
 281   
             {
 282  10
                 attributes.add( attribute );
 283   
             }
 284   
         }
 285  12
         return (Attribute[])attributes.toArray( new Attribute[ attributes.size() ] );
 286   
     }
 287   
 
 288   
     /**
 289   
      * Build a set of Attribute instances for a JavaField.
 290   
      * Use Interceptor to process tags during construction.
 291   
      *
 292   
      * @param field the JavaField
 293   
      * @param interceptor the AttributeInterceptor
 294   
      * @return the Attributes
 295   
      */
 296  10
     private Attribute[] buildAttributes( final JavaField field,
 297   
                                          final QDoxAttributeInterceptor interceptor )
 298   
     {
 299  10
         final ArrayList attributes = new ArrayList();
 300  10
         final DocletTag[] tags = field.getTags();
 301  10
         for( int i = 0; i < tags.length; i++ )
 302   
         {
 303  12
             final Attribute originalAttribute = buildAttribute( tags[ i ] );
 304  12
             final Attribute attribute =
 305   
                 interceptor.processFieldAttribute( field, originalAttribute );
 306  12
             if( null != attribute )
 307   
             {
 308  10
                 attributes.add( attribute );
 309   
             }
 310   
         }
 311  10
         return (Attribute[])attributes.toArray( new Attribute[ attributes.size() ] );
 312   
     }
 313   
 
 314   
     /**
 315   
      * Build an Attribute object from a DocletTag.
 316   
      *
 317   
      * @param tag the DocletTag instance.
 318   
      * @return the Attribute
 319   
      */
 320  72
     Attribute buildAttribute( final DocletTag tag )
 321   
     {
 322  72
         final String name = tag.getName();
 323  72
         final String value = tag.getValue();
 324  72
         if( null == value || "".equals( value.trim() ) )
 325   
         {
 326  68
             return new Attribute( name );
 327   
         }
 328   
 
 329  4
         final Properties parameters = parseValueIntoParameters( value );
 330  4
         if( null == parameters )
 331   
         {
 332  2
             return new Attribute( name, value );
 333   
         }
 334   
         else
 335   
         {
 336  2
             return new Attribute( name, parameters );
 337   
         }
 338   
     }
 339   
 
 340   
     /**
 341   
      * Parse the value string into a set of parameters.
 342   
      * The parameters must match the pattern
 343   
      *
 344   
      * <pre>
 345   
      * ^[ \t\r\n]*([a-zA-Z\_][a-zA-Z0-9\_]*=\"[^\"]*\"[ \t\r\n]+)+
 346   
      * </pre>
 347   
      *
 348   
      * <p>If the value does not match this pattern then null is returned
 349   
      * other wise the key=value pairs are parsed out and placed in
 350   
      * a properties object.</p>
 351   
      *
 352   
      * @param input the input value
 353   
      * @return the parameters if matches patterns, else null
 354   
      */
 355  34
     Properties parseValueIntoParameters( final String input )
 356   
     {
 357  34
         final Properties parameters = new Properties();
 358   
 
 359  34
         final StringBuffer key = new StringBuffer();
 360  34
         final StringBuffer value = new StringBuffer();
 361   
 
 362  34
         int state = PARSE_KEY_START;
 363  34
         final int length = input.length();
 364  34
         for( int i = 0; i < length; i++ )
 365   
         {
 366  494
             final char ch = input.charAt( i );
 367  494
             switch( state )
 368   
             {
 369   
                 case PARSE_KEY_START:
 370  82
                     if( Character.isWhitespace( ch ) )
 371   
                     {
 372  36
                         continue;
 373   
                     }
 374  46
                     else if( Character.isJavaIdentifierStart( ch ) )
 375   
                     {
 376  44
                         key.append( ch );
 377  44
                         state = PARSE_KEY;
 378   
                     }
 379   
                     else
 380   
                     {
 381  2
                         return null;
 382   
                     }
 383  44
                     break;
 384   
 
 385   
                 case PARSE_KEY:
 386  170
                     if( '=' == ch )
 387   
                     {
 388  38
                         state = PARSE_VALUE_START;
 389   
                     }
 390  132
                     else if( Character.isJavaIdentifierPart( ch ) )
 391   
                     {
 392  130
                         key.append( ch );
 393   
                     }
 394   
                     else
 395   
                     {
 396  2
                         return null;
 397   
                     }
 398  168
                     break;
 399   
 
 400   
                 case PARSE_VALUE_START:
 401  34
                     if( '\"' != ch )
 402   
                     {
 403  2
                         return null;
 404   
                     }
 405   
                     else
 406   
                     {
 407  32
                         state = PARSE_VALUE;
 408   
                     }
 409  32
                     break;
 410   
 
 411   
                 case PARSE_VALUE:
 412  190
                     if( '\"' == ch )
 413   
                     {
 414  24
                         state = PARSE_END;
 415  24
                         parameters.setProperty( key.toString(), value.toString() );
 416  24
                         key.setLength( 0 );
 417  24
                         value.setLength( 0 );
 418   
                     }
 419   
                     else
 420   
                     {
 421  166
                         value.append( ch );
 422   
                     }
 423  190
                     break;
 424   
 
 425   
                 case PARSE_END:
 426   
                 default:
 427  18
                     if( Character.isWhitespace( ch ) )
 428   
                     {
 429  16
                         state = PARSE_KEY_START;
 430   
                     }
 431   
                     else
 432   
                     {
 433  2
                         return null;
 434   
                     }
 435  16
                     break;
 436   
             }
 437   
         }
 438   
 
 439  26
         if( PARSE_KEY_START != state &&
 440   
             PARSE_END != state )
 441   
         {
 442  16
             return null;
 443   
         }
 444   
 
 445  10
         return parameters;
 446   
     }
 447   
 }
 448