View Javadoc
1 /* 2 * Copyright (C) The Spice 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.realityforge.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.realityforge.metaclass.model.Attribute; 19 import org.realityforge.metaclass.model.ClassDescriptor; 20 import org.realityforge.metaclass.model.FieldDescriptor; 21 import org.realityforge.metaclass.model.MethodDescriptor; 22 import org.realityforge.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 public ClassDescriptor buildClassDescriptor( final JavaClass javaClass ) 70 { 71 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 public ClassDescriptor buildClassDescriptor( final JavaClass javaClass, 82 final QDoxAttributeInterceptor[] interceptors ) 83 { 84 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 public ClassDescriptor buildClassDescriptor( final JavaClass javaClass, 95 final QDoxAttributeInterceptor interceptor ) 96 { 97 final String classname = javaClass.getFullyQualifiedName(); 98 final Attribute[] originalAttributes = buildAttributes( javaClass, interceptor ); 99 final Attribute[] attributes = 100 interceptor.processClassAttributes( javaClass, originalAttributes ); 101 102 final FieldDescriptor[] fields = 103 buildFields( javaClass.getFields(), interceptor ); 104 final MethodDescriptor[] methods = 105 buildMethods( javaClass.getMethods(), interceptor ); 106 107 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 MethodDescriptor[] buildMethods( final JavaMethod[] methods, 122 final QDoxAttributeInterceptor interceptor ) 123 { 124 final MethodDescriptor[] methodDescriptors = new MethodDescriptor[ methods.length ]; 125 for( int i = 0; i < methods.length; i++ ) 126 { 127 methodDescriptors[ i ] = buildMethod( methods[ i ], interceptor ); 128 } 129 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 MethodDescriptor buildMethod( final JavaMethod method, 140 final QDoxAttributeInterceptor interceptor ) 141 { 142 final String name = method.getName(); 143 final Type returns = method.getReturns(); 144 final String type; 145 if( null != returns ) 146 { 147 type = returns.getValue(); 148 } 149 else 150 { 151 type = ""; 152 } 153 154 final Attribute[] originalAttributes = buildAttributes( method, interceptor ); 155 final Attribute[] attributes = 156 interceptor.processMethodAttributes( method, originalAttributes ); 157 final ParameterDescriptor[] parameters = 158 buildParameters( method.getParameters() ); 159 160 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 ParameterDescriptor[] buildParameters( final JavaParameter[] parameters ) 174 { 175 final ParameterDescriptor[] descriptors = 176 new ParameterDescriptor[ parameters.length ]; 177 for( int i = 0; i < parameters.length; i++ ) 178 { 179 descriptors[ i ] = buildParameter( parameters[ i ] ); 180 } 181 return descriptors; 182 } 183 184 /*** 185 * Build a ParameterDescriptor for a JavaParameter. 186 * 187 * @param parameter the JavaParameter 188 * @return the ParameterDescriptor 189 */ 190 ParameterDescriptor buildParameter( final JavaParameter parameter ) 191 { 192 final String name = parameter.getName(); 193 final String value = parameter.getType().getValue(); 194 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 FieldDescriptor[] buildFields( final JavaField[] fields, 205 final QDoxAttributeInterceptor interceptor ) 206 { 207 final FieldDescriptor[] fieldDescriptors = new FieldDescriptor[ fields.length ]; 208 for( int i = 0; i < fields.length; i++ ) 209 { 210 fieldDescriptors[ i ] = buildField( fields[ i ], interceptor ); 211 } 212 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 FieldDescriptor buildField( final JavaField field, 223 final QDoxAttributeInterceptor interceptor ) 224 { 225 final String name = field.getName(); 226 final String type = field.getType().getValue(); 227 final Attribute[] originalAttributes = buildAttributes( field, interceptor ); 228 final Attribute[] attributes = 229 interceptor.processFieldAttributes( field, originalAttributes ); 230 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 private Attribute[] buildAttributes( final JavaClass javaClass, 245 final QDoxAttributeInterceptor interceptor ) 246 { 247 final ArrayList attributes = new ArrayList(); 248 final DocletTag[] tags = javaClass.getTags(); 249 for( int i = 0; i < tags.length; i++ ) 250 { 251 final Attribute originalAttribute = buildAttribute( tags[ i ] ); 252 final Attribute attribute = 253 interceptor.processClassAttribute( javaClass, originalAttribute ); 254 if( null != attribute ) 255 { 256 attributes.add( attribute ); 257 } 258 } 259 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 private Attribute[] buildAttributes( final JavaMethod method, 271 final QDoxAttributeInterceptor interceptor ) 272 { 273 final ArrayList attributes = new ArrayList(); 274 final DocletTag[] tags = method.getTags(); 275 for( int i = 0; i < tags.length; i++ ) 276 { 277 final Attribute originalAttribute = buildAttribute( tags[ i ] ); 278 final Attribute attribute = 279 interceptor.processMethodAttribute( method, originalAttribute ); 280 if( null != attribute ) 281 { 282 attributes.add( attribute ); 283 } 284 } 285 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 private Attribute[] buildAttributes( final JavaField field, 297 final QDoxAttributeInterceptor interceptor ) 298 { 299 final ArrayList attributes = new ArrayList(); 300 final DocletTag[] tags = field.getTags(); 301 for( int i = 0; i < tags.length; i++ ) 302 { 303 final Attribute originalAttribute = buildAttribute( tags[ i ] ); 304 final Attribute attribute = 305 interceptor.processFieldAttribute( field, originalAttribute ); 306 if( null != attribute ) 307 { 308 attributes.add( attribute ); 309 } 310 } 311 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 Attribute buildAttribute( final DocletTag tag ) 321 { 322 final String name = tag.getName(); 323 final String value = tag.getValue(); 324 if( null == value || "".equals( value.trim() ) ) 325 { 326 return new Attribute( name ); 327 } 328 329 final Properties parameters = parseValueIntoParameters( value ); 330 if( null == parameters ) 331 { 332 return new Attribute( name, value ); 333 } 334 else 335 { 336 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 Properties parseValueIntoParameters( final String input ) 356 { 357 final Properties parameters = new Properties(); 358 359 final StringBuffer key = new StringBuffer(); 360 final StringBuffer value = new StringBuffer(); 361 362 int state = PARSE_KEY_START; 363 final int length = input.length(); 364 for( int i = 0; i < length; i++ ) 365 { 366 final char ch = input.charAt( i ); 367 switch( state ) 368 { 369 case PARSE_KEY_START: 370 if( Character.isWhitespace( ch ) ) 371 { 372 continue; 373 } 374 else if( Character.isJavaIdentifierStart( ch ) ) 375 { 376 key.append( ch ); 377 state = PARSE_KEY; 378 } 379 else 380 { 381 return null; 382 } 383 break; 384 385 case PARSE_KEY: 386 if( '=' == ch ) 387 { 388 state = PARSE_VALUE_START; 389 } 390 else if( Character.isJavaIdentifierPart( ch ) ) 391 { 392 key.append( ch ); 393 } 394 else 395 { 396 return null; 397 } 398 break; 399 400 case PARSE_VALUE_START: 401 if( '\"' != ch ) 402 { 403 return null; 404 } 405 else 406 { 407 state = PARSE_VALUE; 408 } 409 break; 410 411 case PARSE_VALUE: 412 if( '\"' == ch ) 413 { 414 state = PARSE_END; 415 parameters.setProperty( key.toString(), value.toString() ); 416 key.setLength( 0 ); 417 value.setLength( 0 ); 418 } 419 else 420 { 421 value.append( ch ); 422 } 423 break; 424 425 case PARSE_END: 426 default: 427 if( Character.isWhitespace( ch ) ) 428 { 429 state = PARSE_KEY_START; 430 } 431 else 432 { 433 return null; 434 } 435 break; 436 } 437 } 438 439 if( PARSE_KEY_START != state && 440 PARSE_END != state ) 441 { 442 return null; 443 } 444 445 return parameters; 446 } 447 }

This page was automatically generated by Maven