1 package org.apache.maven.tools.plugin.extractor.java; 2 3 18 19 import com.thoughtworks.qdox.JavaDocBuilder; 20 import com.thoughtworks.qdox.model.DocletTag; 21 import com.thoughtworks.qdox.model.JavaClass; 22 import com.thoughtworks.qdox.model.JavaField; 23 import com.thoughtworks.qdox.model.JavaSource; 24 import org.apache.maven.plugin.descriptor.InvalidParameterException; 25 import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException; 26 import org.apache.maven.plugin.descriptor.MojoDescriptor; 27 import org.apache.maven.plugin.descriptor.Parameter; 28 import org.apache.maven.plugin.descriptor.PluginDescriptor; 29 import org.apache.maven.plugin.descriptor.Requirement; 30 import org.apache.maven.project.MavenProject; 31 import org.apache.maven.tools.plugin.extractor.MojoDescriptorExtractor; 32 import org.codehaus.plexus.logging.AbstractLogEnabled; 33 import org.codehaus.plexus.util.StringUtils; 34 35 import java.io.File ; 36 import java.util.ArrayList ; 37 import java.util.Iterator ; 38 import java.util.List ; 39 import java.util.Map ; 40 import java.util.TreeMap ; 41 42 43 48 public class JavaMojoDescriptorExtractor 49 extends AbstractLogEnabled 50 implements MojoDescriptorExtractor 51 { 52 public static final String MAVEN_PLUGIN_INSTANTIATION = "instantiationStrategy"; 53 54 public static final String CONFIGURATOR = "configurator"; 55 56 public static final String PARAMETER = "parameter"; 57 58 public static final String PARAMETER_EXPRESSION = "expression"; 59 60 public static final String PARAMETER_DEFAULT_VALUE = "default-value"; 61 62 72 public static final String PARAMETER_PROPERTY = "property"; 73 74 public static final String REQUIRED = "required"; 75 76 public static final String DEPRECATED = "deprecated"; 77 78 public static final String READONLY = "readonly"; 79 80 public static final String GOAL = "goal"; 81 82 public static final String PHASE = "phase"; 83 84 public static final String EXECUTE = "execute"; 85 86 public static final String GOAL_DESCRIPTION = "description"; 87 88 public static final String GOAL_REQUIRES_DEPENDENCY_RESOLUTION = "requiresDependencyResolution"; 89 90 public static final String GOAL_REQUIRES_PROJECT = "requiresProject"; 91 92 public static final String GOAL_REQUIRES_REPORTS = "requiresReports"; 93 94 public static final String GOAL_IS_AGGREGATOR = "aggregator"; 95 96 public static final String GOAL_REQUIRES_ONLINE = "requiresOnline"; 97 98 public static final String GOAL_INHERIT_BY_DEFAULT = "inheritByDefault"; 99 100 public static final String GOAL_MULTI_EXECUTION_STRATEGY = "attainAlways"; 101 102 public static final String GOAL_REQUIRES_DIRECT_INVOCATION = "requiresDirectInvocation"; 103 104 private static final String COMPONENT = "component"; 105 106 protected void validateParameter( Parameter parameter, int i ) 107 throws InvalidParameterException 108 { 109 String name = parameter.getName(); 111 112 if ( name == null ) 113 { 114 throw new InvalidParameterException( "name", i ); 115 } 116 117 String type = parameter.getType(); 119 120 if ( type == null ) 121 { 122 throw new InvalidParameterException( "type", i ); 123 } 124 125 String description = parameter.getDescription(); 127 128 if ( description == null ) 129 { 130 throw new InvalidParameterException( "description", i ); 131 } 132 } 133 134 138 private MojoDescriptor createMojoDescriptor( JavaSource javaSource, PluginDescriptor pluginDescriptor ) 139 throws InvalidPluginDescriptorException 140 { 141 MojoDescriptor mojoDescriptor = new MojoDescriptor(); 142 143 mojoDescriptor.setPluginDescriptor( pluginDescriptor ); 144 145 JavaClass javaClass = getJavaClass( javaSource ); 146 147 mojoDescriptor.setLanguage( "java" ); 148 149 mojoDescriptor.setImplementation( javaClass.getFullyQualifiedName() ); 150 151 mojoDescriptor.setDescription( javaClass.getComment() ); 152 153 DocletTag tag = findInClassHierarchy( javaClass, MAVEN_PLUGIN_INSTANTIATION ); 154 155 if ( tag != null ) 156 { 157 mojoDescriptor.setInstantiationStrategy( tag.getValue() ); 158 } 159 160 tag = findInClassHierarchy( javaClass, GOAL_MULTI_EXECUTION_STRATEGY ); 161 162 if ( tag != null ) 163 { 164 mojoDescriptor.setExecutionStrategy( MojoDescriptor.MULTI_PASS_EXEC_STRATEGY ); 165 } 166 else 167 { 168 mojoDescriptor.setExecutionStrategy( MojoDescriptor.SINGLE_PASS_EXEC_STRATEGY ); 169 } 170 171 175 DocletTag configurator = findInClassHierarchy( javaClass, CONFIGURATOR ); 176 177 if ( configurator != null ) 178 { 179 mojoDescriptor.setComponentConfigurator( configurator.getValue() ); 180 } 181 182 186 DocletTag goal = findInClassHierarchy( javaClass, GOAL ); 187 188 if ( goal != null ) 189 { 190 mojoDescriptor.setGoal( goal.getValue() ); 191 } 192 193 197 DocletTag phase = findInClassHierarchy( javaClass, PHASE ); 198 199 if ( phase != null ) 200 { 201 mojoDescriptor.setPhase( phase.getValue() ); 202 } 203 204 208 DocletTag execute = findInClassHierarchy( javaClass, EXECUTE ); 209 210 if ( execute != null ) 211 { 212 String executePhase = execute.getNamedParameter( "phase" ); 213 String executeGoal = execute.getNamedParameter( "goal" ); 214 215 if ( executePhase == null && executeGoal == null ) 216 { 217 throw new InvalidPluginDescriptorException( "@execute tag requires a 'phase' or 'goal' parameter" ); 218 } 219 else if ( executePhase != null && executeGoal != null ) 220 { 221 throw new InvalidPluginDescriptorException( 222 "@execute tag can have only one of a 'phase' or 'goal' parameter" ); 223 } 224 mojoDescriptor.setExecutePhase( executePhase ); 225 mojoDescriptor.setExecuteGoal( executeGoal ); 226 227 String lifecycle = execute.getNamedParameter( "lifecycle" ); 228 229 if ( lifecycle != null ) 230 { 231 mojoDescriptor.setExecuteLifecycle( lifecycle ); 232 if ( mojoDescriptor.getExecuteGoal() != null ) 233 { 234 throw new InvalidPluginDescriptorException( 235 "@execute lifecycle requires a phase instead of a goal" ); 236 } 237 } 238 } 239 240 244 DocletTag requiresDependencyResolution = findInClassHierarchy( javaClass, GOAL_REQUIRES_DEPENDENCY_RESOLUTION ); 245 246 if ( requiresDependencyResolution != null ) 247 { 248 String value = requiresDependencyResolution.getValue(); 249 250 if ( value == null || value.length() == 0 ) 251 { 252 value = "runtime"; 253 } 254 255 mojoDescriptor.setDependencyResolutionRequired( value ); 256 } 257 258 262 boolean value = getBooleanTagValue( javaClass, GOAL_REQUIRES_PROJECT, mojoDescriptor.isProjectRequired() ); 263 mojoDescriptor.setProjectRequired( value ); 264 265 269 DocletTag aggregator = findInClassHierarchy( javaClass, GOAL_IS_AGGREGATOR ); 270 271 if ( aggregator != null ) 272 { 273 mojoDescriptor.setAggregator( true ); 274 } 275 276 280 value = getBooleanTagValue( javaClass, GOAL_REQUIRES_DIRECT_INVOCATION, 281 mojoDescriptor.isDirectInvocationOnly() ); 282 mojoDescriptor.setDirectInvocationOnly( value ); 283 284 288 value = getBooleanTagValue( javaClass, GOAL_REQUIRES_ONLINE, mojoDescriptor.isOnlineRequired() ); 289 mojoDescriptor.setOnlineRequired( value ); 290 291 295 value = getBooleanTagValue( javaClass, GOAL_INHERIT_BY_DEFAULT, mojoDescriptor.isInheritedByDefault() ); 296 mojoDescriptor.setInheritedByDefault( value ); 297 298 extractParameters( mojoDescriptor, javaClass ); 299 300 return mojoDescriptor; 301 } 302 303 private static boolean getBooleanTagValue( JavaClass javaClass, String tagName, boolean defaultValue ) 304 { 305 DocletTag requiresProject = findInClassHierarchy( javaClass, tagName ); 306 307 if ( requiresProject != null ) 308 { 309 String requiresProjectValue = requiresProject.getValue(); 310 311 if ( requiresProjectValue != null && requiresProjectValue.length() > 0 ) 312 { 313 defaultValue = Boolean.valueOf( requiresProjectValue ).booleanValue(); 314 } 315 } 316 return defaultValue; 317 } 318 319 private static DocletTag findInClassHierarchy( JavaClass javaClass, String tagName ) 320 { 321 DocletTag tag = javaClass.getTagByName( tagName ); 322 323 if ( tag == null ) 324 { 325 JavaClass superClass = javaClass.getSuperJavaClass(); 326 327 if ( superClass != null ) 328 { 329 tag = findInClassHierarchy( superClass, tagName ); 330 } 331 } 332 333 return tag; 334 } 335 336 private void extractParameters( MojoDescriptor mojoDescriptor, JavaClass javaClass ) 337 throws InvalidPluginDescriptorException 338 { 339 343 Map rawParams = extractFieldParameterTags( javaClass ); 344 345 for ( Iterator it = rawParams.entrySet().iterator(); it.hasNext(); ) 346 { 347 Map.Entry entry = (Map.Entry ) it.next(); 348 349 JavaField field = (JavaField) entry.getValue(); 350 351 Parameter pd = new Parameter(); 352 353 pd.setType( field.getType().getValue() ); 354 355 pd.setDescription( field.getComment() ); 356 357 DocletTag componentTag = field.getTagByName( COMPONENT ); 358 359 if ( componentTag != null ) 360 { 361 String role = componentTag.getNamedParameter( "role" ); 362 363 if ( role == null ) 364 { 365 role = field.getType().toString(); 366 } 367 368 String roleHint = componentTag.getNamedParameter( "roleHint" ); 369 370 pd.setRequirement( new Requirement( role, roleHint ) ); 371 372 pd.setName( (String ) entry.getKey() ); 373 } 374 else 375 { 376 DocletTag parameter = field.getTagByName( PARAMETER ); 377 378 388 String property = parameter.getNamedParameter( PARAMETER_PROPERTY ); 389 390 if ( !StringUtils.isEmpty( property ) ) 391 { 392 pd.setName( property ); 393 } 394 else 395 { 396 pd.setName( (String ) entry.getKey() ); 397 } 398 399 pd.setRequired( field.getTagByName( REQUIRED ) != null ); 400 401 pd.setEditable( field.getTagByName( READONLY ) == null ); 402 403 DocletTag deprecationTag = field.getTagByName( DEPRECATED ); 404 405 if ( deprecationTag != null ) 406 { 407 pd.setDeprecated( deprecationTag.getValue() ); 408 } 409 410 String alias = parameter.getNamedParameter( "alias" ); 411 412 if ( !StringUtils.isEmpty( alias ) ) 413 { 414 pd.setAlias( alias ); 415 } 416 417 pd.setExpression( parameter.getNamedParameter( PARAMETER_EXPRESSION ) ); 418 419 if ( "${reports}".equals( pd.getExpression() ) ) 420 { 421 mojoDescriptor.setRequiresReports( true ); 422 } 423 424 pd.setDefaultValue( parameter.getNamedParameter( PARAMETER_DEFAULT_VALUE ) ); 425 } 426 427 mojoDescriptor.addParameter( pd ); 428 } 429 } 430 431 private Map extractFieldParameterTags( JavaClass javaClass ) 432 { 433 Map rawParams; 434 435 JavaClass superClass = javaClass.getSuperJavaClass(); 438 439 if ( superClass != null ) 440 { 441 rawParams = extractFieldParameterTags( superClass ); 442 } 443 else 444 { 445 rawParams = new TreeMap (); 446 } 447 448 JavaField[] classFields = javaClass.getFields(); 449 450 if ( classFields != null ) 451 { 452 for ( int i = 0; i < classFields.length; i++ ) 453 { 454 JavaField field = classFields[i]; 455 456 if ( field.getTagByName( PARAMETER ) != null || field.getTagByName( COMPONENT ) != null ) 457 { 458 rawParams.put( field.getName(), field ); 459 } 460 } 461 } 462 return rawParams; 463 } 464 465 private JavaClass getJavaClass( JavaSource javaSource ) 466 { 467 return javaSource.getClasses()[0]; 468 } 469 470 public List execute( MavenProject project, PluginDescriptor pluginDescriptor ) 471 throws InvalidPluginDescriptorException 472 { 473 JavaDocBuilder builder = new JavaDocBuilder(); 474 475 for ( Iterator i = project.getCompileSourceRoots().iterator(); i.hasNext(); ) 476 { 477 builder.addSourceTree( new File ( (String ) i.next() ) ); 478 } 479 480 JavaSource[] javaSources = builder.getSources(); 481 482 List descriptors = new ArrayList (); 483 484 for ( int i = 0; i < javaSources.length; i++ ) 485 { 486 JavaClass javaClass = getJavaClass( javaSources[i] ); 487 488 DocletTag tag = javaClass.getTagByName( GOAL ); 489 490 if ( tag != null ) 491 { 492 MojoDescriptor mojoDescriptor = createMojoDescriptor( javaSources[i], pluginDescriptor ); 493 494 499 List parameters = mojoDescriptor.getParameters(); 500 501 if ( parameters != null ) 502 { 503 for ( int j = 0; j < parameters.size(); j++ ) 504 { 505 validateParameter( (Parameter) parameters.get( j ), j ); 506 } 507 } 508 509 531 descriptors.add( mojoDescriptor ); 532 } 533 } 534 535 return descriptors; 536 } 537 538 } 539 | Popular Tags |