001 package org.apache.maven.tools.plugin.annotations;
002
003 /*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements. See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership. The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License. You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied. See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022 import com.thoughtworks.qdox.JavaDocBuilder;
023 import com.thoughtworks.qdox.model.DocletTag;
024 import com.thoughtworks.qdox.model.JavaClass;
025 import com.thoughtworks.qdox.model.JavaField;
026 import org.apache.maven.artifact.Artifact;
027 import org.apache.maven.artifact.factory.ArtifactFactory;
028 import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
029 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
030 import org.apache.maven.artifact.resolver.ArtifactResolver;
031 import org.apache.maven.plugin.descriptor.DuplicateParameterException;
032 import org.apache.maven.plugin.descriptor.InvalidParameterException;
033 import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException;
034 import org.apache.maven.plugin.descriptor.MojoDescriptor;
035 import org.apache.maven.plugin.descriptor.PluginDescriptor;
036 import org.apache.maven.plugin.descriptor.Requirement;
037 import org.apache.maven.project.MavenProject;
038 import org.apache.maven.tools.plugin.DefaultPluginToolsRequest;
039 import org.apache.maven.tools.plugin.ExtendedMojoDescriptor;
040 import org.apache.maven.tools.plugin.PluginToolsRequest;
041 import org.apache.maven.tools.plugin.annotations.datamodel.ComponentAnnotationContent;
042 import org.apache.maven.tools.plugin.annotations.datamodel.ExecuteAnnotationContent;
043 import org.apache.maven.tools.plugin.annotations.datamodel.MojoAnnotationContent;
044 import org.apache.maven.tools.plugin.annotations.datamodel.ParameterAnnotationContent;
045 import org.apache.maven.tools.plugin.annotations.scanner.MojoAnnotatedClass;
046 import org.apache.maven.tools.plugin.annotations.scanner.MojoAnnotationsScanner;
047 import org.apache.maven.tools.plugin.annotations.scanner.MojoAnnotationsScannerRequest;
048 import org.apache.maven.tools.plugin.extractor.ExtractionException;
049 import org.apache.maven.tools.plugin.extractor.MojoDescriptorExtractor;
050 import org.apache.maven.tools.plugin.util.PluginUtils;
051 import org.codehaus.plexus.archiver.UnArchiver;
052 import org.codehaus.plexus.archiver.manager.ArchiverManager;
053 import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
054 import org.codehaus.plexus.component.annotations.Component;
055 import org.codehaus.plexus.logging.AbstractLogEnabled;
056 import org.codehaus.plexus.util.StringUtils;
057
058 import java.io.File;
059 import java.util.ArrayList;
060 import java.util.Arrays;
061 import java.util.Collection;
062 import java.util.Collections;
063 import java.util.HashMap;
064 import java.util.HashSet;
065 import java.util.List;
066 import java.util.Map;
067 import java.util.Set;
068 import java.util.TreeMap;
069 import java.util.TreeSet;
070
071 /**
072 * JavaMojoDescriptorExtractor, a MojoDescriptor extractor to read descriptors from java classes with annotations.
073 *
074 * @author Olivier Lamy
075 * @since 3.0
076 */
077 @Component( role = MojoDescriptorExtractor.class, hint = "java-annotations" )
078 public class JavaAnnotationsMojoDescriptorExtractor
079 extends AbstractLogEnabled
080 implements MojoDescriptorExtractor
081 {
082
083 @org.codehaus.plexus.component.annotations.Requirement
084 private MojoAnnotationsScanner mojoAnnotationsScanner;
085
086 @org.codehaus.plexus.component.annotations.Requirement
087 private ArtifactResolver artifactResolver;
088
089 @org.codehaus.plexus.component.annotations.Requirement
090 private ArtifactFactory artifactFactory;
091
092 @org.codehaus.plexus.component.annotations.Requirement
093 private ArchiverManager archiverManager;
094
095 public List<MojoDescriptor> execute( MavenProject project, PluginDescriptor pluginDescriptor )
096 throws ExtractionException, InvalidPluginDescriptorException
097 {
098 return execute( new DefaultPluginToolsRequest( project, pluginDescriptor ) );
099 }
100
101 public List<MojoDescriptor> execute( PluginToolsRequest request )
102 throws ExtractionException, InvalidPluginDescriptorException
103 {
104 Map<String, MojoAnnotatedClass> mojoAnnotatedClasses = scanAnnotations( request );
105
106 Map<String, JavaClass> javaClassesMap = scanJavadoc( request, mojoAnnotatedClasses.values() );
107
108 populateDataFromJavadoc( mojoAnnotatedClasses, javaClassesMap );
109
110 return toMojoDescriptors( mojoAnnotatedClasses, request.getPluginDescriptor() );
111 }
112
113 private Map<String, MojoAnnotatedClass> scanAnnotations( PluginToolsRequest request )
114 throws ExtractionException
115 {
116 MojoAnnotationsScannerRequest mojoAnnotationsScannerRequest = new MojoAnnotationsScannerRequest();
117
118 File output = new File( request.getProject().getBuild().getOutputDirectory() );
119 mojoAnnotationsScannerRequest.setClassesDirectories( Arrays.asList( output ) );
120
121 mojoAnnotationsScannerRequest.setDependencies( request.getDependencies() );
122
123 mojoAnnotationsScannerRequest.setProject( request.getProject() );
124
125 return mojoAnnotationsScanner.scan( mojoAnnotationsScannerRequest );
126 }
127
128 private Map<String, JavaClass> scanJavadoc( PluginToolsRequest request,
129 Collection<MojoAnnotatedClass> mojoAnnotatedClasses )
130 throws ExtractionException
131 {
132 // found artifact from reactors to scan sources
133 // we currently only scan sources from reactors
134 List<MavenProject> mavenProjects = new ArrayList<MavenProject>();
135
136 // if we need to scan sources from external artifacts
137 Set<Artifact> externalArtifacts = new HashSet<Artifact>();
138
139 for ( MojoAnnotatedClass mojoAnnotatedClass : mojoAnnotatedClasses )
140 {
141 if ( StringUtils.equals( mojoAnnotatedClass.getArtifact().getArtifactId(),
142 request.getProject().getArtifact().getArtifactId() ) )
143 {
144 continue;
145 }
146
147 if ( !isMojoAnnnotatedClassCandidate( mojoAnnotatedClass ) )
148 {
149 // we don't scan sources for classes without mojo annotations
150 continue;
151 }
152
153 MavenProject mavenProject =
154 getFromProjectReferences( mojoAnnotatedClass.getArtifact(), request.getProject() );
155
156 if ( mavenProject != null )
157 {
158 mavenProjects.add( mavenProject );
159 }
160 else
161 {
162 externalArtifacts.add( mojoAnnotatedClass.getArtifact() );
163 }
164 }
165
166 Map<String, JavaClass> javaClassesMap = new HashMap<String, JavaClass>();
167
168 // try to get artifact with sources classifier, extract somewhere then scan for @since, @deprecated
169 for ( Artifact artifact : externalArtifacts )
170 {
171 // parameter for test-sources too ?? olamy I need that for it test only
172 if ( StringUtils.equalsIgnoreCase( "tests", artifact.getClassifier() ) )
173 {
174 javaClassesMap.putAll( discoverClassesFromSourcesJar( artifact, request, "test-sources" ) );
175 }
176 else
177 {
178 javaClassesMap.putAll( discoverClassesFromSourcesJar( artifact, request, "sources" ) );
179 }
180
181 }
182
183 for ( MavenProject mavenProject : mavenProjects )
184 {
185 javaClassesMap.putAll( discoverClasses( request.getEncoding(), mavenProject ) );
186 }
187
188 javaClassesMap.putAll( discoverClasses( request ) );
189
190 return javaClassesMap;
191 }
192
193 private boolean isMojoAnnnotatedClassCandidate( MojoAnnotatedClass mojoAnnotatedClass )
194 {
195 if ( mojoAnnotatedClass == null )
196 {
197 return false;
198 }
199 return ( !mojoAnnotatedClass.getComponents().isEmpty() || !mojoAnnotatedClass.getParameters().isEmpty()
200 || mojoAnnotatedClass.getExecute() != null || mojoAnnotatedClass.getMojo() != null );
201
202 }
203
204 protected Map<String, JavaClass> discoverClassesFromSourcesJar( Artifact artifact, PluginToolsRequest request,
205 String classifier )
206 throws ExtractionException
207 {
208 try
209 {
210 Artifact sourcesArtifact =
211 artifactFactory.createArtifactWithClassifier( artifact.getGroupId(), artifact.getArtifactId(),
212 artifact.getVersion(), artifact.getType(), classifier );
213
214 artifactResolver.resolve( sourcesArtifact, request.getRemoteRepos(), request.getLocal() );
215
216 if ( sourcesArtifact.getFile() == null || !sourcesArtifact.getFile().exists() )
217 {
218 // could not get artifact sources
219 return Collections.emptyMap();
220 }
221
222 // extract sources to target/maven-plugin-plugin-sources/${groupId}/${artifact}/sources
223 File extractDirectory = new File( request.getProject().getBuild().getDirectory(),
224 "maven-plugin-plugin-sources/" + sourcesArtifact.getGroupId() + "/"
225 + sourcesArtifact.getArtifactId() + "/" + sourcesArtifact.getVersion()
226 + "/" + sourcesArtifact.getClassifier() );
227 extractDirectory.mkdirs();
228
229 UnArchiver unArchiver = archiverManager.getUnArchiver( "jar" );
230 unArchiver.setSourceFile( sourcesArtifact.getFile() );
231 unArchiver.setDestDirectory( extractDirectory );
232 unArchiver.extract();
233
234 return discoverClasses( request.getEncoding(), Arrays.asList( extractDirectory ) );
235 }
236 catch ( ArtifactResolutionException e )
237 {
238 throw new ExtractionException( e.getMessage(), e );
239 }
240 catch ( ArtifactNotFoundException e )
241 {
242 //throw new ExtractionException( e.getMessage(), e );
243 getLogger().debug( "skip ArtifactNotFoundException:" + e.getMessage() );
244 getLogger().warn(
245 "Unable to get sources artifact for " + artifact.getGroupId() + ":" + artifact.getArtifactId() + ":"
246 + artifact.getVersion() + ". Some javadoc tags (@since, @deprecated and comments) won't be used" );
247 return Collections.emptyMap();
248 }
249 catch ( NoSuchArchiverException e )
250 {
251 throw new ExtractionException( e.getMessage(), e );
252 }
253 }
254
255 /**
256 * from sources scan to get @since and @deprecated and description of classes and fields.
257 *
258 * @param mojoAnnotatedClasses
259 * @param javaClassesMap
260 */
261 protected void populateDataFromJavadoc( Map<String, MojoAnnotatedClass> mojoAnnotatedClasses,
262 Map<String, JavaClass> javaClassesMap )
263 {
264
265 for ( Map.Entry<String, MojoAnnotatedClass> entry : mojoAnnotatedClasses.entrySet() )
266 {
267 JavaClass javaClass = javaClassesMap.get( entry.getKey() );
268 if ( javaClass == null )
269 {
270 continue;
271 }
272
273 // populate class-level content
274 MojoAnnotationContent mojoAnnotationContent = entry.getValue().getMojo();
275 if ( mojoAnnotationContent != null )
276 {
277 mojoAnnotationContent.setDescription( javaClass.getComment() );
278
279 DocletTag since = findInClassHierarchy( javaClass, "since" );
280 if ( since != null )
281 {
282 mojoAnnotationContent.setSince( since.getValue() );
283 }
284
285 DocletTag deprecated = findInClassHierarchy( javaClass, "deprecated" );
286 if ( deprecated != null )
287 {
288 mojoAnnotationContent.setDeprecated( deprecated.getValue() );
289 }
290 }
291
292 Map<String, JavaField> fieldsMap = extractFieldParameterTags( javaClass, javaClassesMap );
293
294 // populate parameters
295 Map<String, ParameterAnnotationContent> parameters =
296 getParametersParentHierarchy( entry.getValue(), new HashMap<String, ParameterAnnotationContent>(),
297 mojoAnnotatedClasses );
298 for ( Map.Entry<String, ParameterAnnotationContent> parameter : new TreeMap<String, ParameterAnnotationContent>(
299 parameters ).entrySet() )
300 {
301 JavaField javaField = fieldsMap.get( parameter.getKey() );
302 if ( javaField == null )
303 {
304 continue;
305 }
306
307 ParameterAnnotationContent parameterAnnotationContent = parameter.getValue();
308 parameterAnnotationContent.setDescription( javaField.getComment() );
309
310 DocletTag deprecated = javaField.getTagByName( "deprecated" );
311 if ( deprecated != null )
312 {
313 parameterAnnotationContent.setDeprecated( deprecated.getValue() );
314 }
315
316 DocletTag since = javaField.getTagByName( "since" );
317 if ( since != null )
318 {
319 parameterAnnotationContent.setSince( since.getValue() );
320 }
321 }
322
323 // populate components
324 for ( Map.Entry<String, ComponentAnnotationContent> component : entry.getValue().getComponents().entrySet() )
325 {
326 JavaField javaField = fieldsMap.get( component.getKey() );
327 if ( javaField == null )
328 {
329 continue;
330 }
331
332 ComponentAnnotationContent componentAnnotationContent = component.getValue();
333 componentAnnotationContent.setDescription( javaField.getComment() );
334
335 DocletTag deprecated = javaField.getTagByName( "deprecated" );
336 if ( deprecated != null )
337 {
338 componentAnnotationContent.setDeprecated( deprecated.getValue() );
339 }
340
341 DocletTag since = javaField.getTagByName( "since" );
342 if ( since != null )
343 {
344 componentAnnotationContent.setSince( since.getValue() );
345 }
346 }
347
348 }
349
350 }
351
352 /**
353 * @param javaClass not null
354 * @param tagName not null
355 * @return docletTag instance
356 */
357 private DocletTag findInClassHierarchy( JavaClass javaClass, String tagName )
358 {
359 DocletTag tag = javaClass.getTagByName( tagName );
360
361 if ( tag == null )
362 {
363 JavaClass superClass = javaClass.getSuperJavaClass();
364
365 if ( superClass != null )
366 {
367 tag = findInClassHierarchy( superClass, tagName );
368 }
369 }
370
371 return tag;
372 }
373
374 /**
375 * extract fields that are either parameters or components.
376 *
377 * @param javaClass not null
378 * @return map with Mojo parameters names as keys
379 */
380 private Map<String, JavaField> extractFieldParameterTags( JavaClass javaClass,
381 Map<String, JavaClass> javaClassesMap )
382 {
383 Map<String, JavaField> rawParams = new TreeMap<String, com.thoughtworks.qdox.model.JavaField>();
384
385 // we have to add the parent fields first, so that they will be overwritten by the local fields if
386 // that actually happens...
387 JavaClass superClass = javaClass.getSuperJavaClass();
388
389 if ( superClass != null )
390 {
391 if ( superClass.getFields().length > 0 )
392 {
393 rawParams = extractFieldParameterTags( superClass, javaClassesMap );
394 }
395 // maybe sources comes from scan of sources artifact
396 superClass = javaClassesMap.get( superClass.getFullyQualifiedName() );
397 if ( superClass != null )
398 {
399 rawParams = extractFieldParameterTags( superClass, javaClassesMap );
400 }
401 }
402 else
403 {
404
405 rawParams = new TreeMap<String, JavaField>();
406 }
407
408 JavaField[] classFields = javaClass.getFields();
409
410 if ( classFields != null )
411 {
412 for ( JavaField field : classFields )
413 {
414 rawParams.put( field.getName(), field );
415 }
416 }
417 return rawParams;
418 }
419
420 protected Map<String, JavaClass> discoverClasses( final PluginToolsRequest request )
421 {
422 return discoverClasses( request.getEncoding(), request.getProject() );
423 }
424
425 @SuppressWarnings( "unchecked" )
426 protected Map<String, JavaClass> discoverClasses( final String encoding, final MavenProject project )
427 {
428 List<File> sources = new ArrayList<File>();
429
430 for ( String source : (List<String>) project.getCompileSourceRoots() )
431 {
432 sources.add( new File( source ) );
433 }
434
435 // TODO be more dynamic
436 File generatedPlugin = new File( project.getBasedir(), "target/generated-sources/plugin" );
437 if ( !project.getCompileSourceRoots().contains( generatedPlugin.getAbsolutePath() )
438 && generatedPlugin.exists() )
439 {
440 sources.add( generatedPlugin );
441 }
442
443 return discoverClasses( encoding, sources );
444 }
445
446 protected Map<String, JavaClass> discoverClasses( final String encoding, List<File> sourceDirectories )
447 {
448 JavaDocBuilder builder = new JavaDocBuilder();
449 builder.setEncoding( encoding );
450
451 for ( File source : sourceDirectories )
452 {
453 builder.addSourceTree( source );
454 }
455
456 JavaClass[] javaClasses = builder.getClasses();
457
458 if ( javaClasses == null || javaClasses.length < 1 )
459 {
460 return Collections.emptyMap();
461 }
462
463 Map<String, JavaClass> javaClassMap = new HashMap<String, JavaClass>( javaClasses.length );
464
465 for ( JavaClass javaClass : javaClasses )
466 {
467 javaClassMap.put( javaClass.getFullyQualifiedName(), javaClass );
468 }
469
470 return javaClassMap;
471 }
472
473 private List<MojoDescriptor> toMojoDescriptors( Map<String, MojoAnnotatedClass> mojoAnnotatedClasses,
474 PluginDescriptor pluginDescriptor )
475 throws DuplicateParameterException, InvalidParameterException
476 {
477 List<MojoDescriptor> mojoDescriptors = new ArrayList<MojoDescriptor>( mojoAnnotatedClasses.size() );
478 for ( MojoAnnotatedClass mojoAnnotatedClass : mojoAnnotatedClasses.values() )
479 {
480 // no mojo so skip it
481 if ( mojoAnnotatedClass.getMojo() == null )
482 {
483 continue;
484 }
485
486 ExtendedMojoDescriptor mojoDescriptor = new ExtendedMojoDescriptor();
487
488 //mojoDescriptor.setRole( mojoAnnotatedClass.getClassName() );
489 //mojoDescriptor.setRoleHint( "default" );
490 mojoDescriptor.setImplementation( mojoAnnotatedClass.getClassName() );
491 mojoDescriptor.setLanguage( "java" );
492
493 MojoAnnotationContent mojo = mojoAnnotatedClass.getMojo();
494
495 mojoDescriptor.setDescription( mojo.getDescription() );
496 mojoDescriptor.setSince( mojo.getSince() );
497 mojo.setDeprecated( mojo.getDeprecated() );
498
499 mojoDescriptor.setProjectRequired( mojo.requiresProject() );
500
501 mojoDescriptor.setRequiresReports( mojo.requiresReports() );
502
503 mojoDescriptor.setComponentConfigurator( mojo.configurator() );
504
505 mojoDescriptor.setInheritedByDefault( mojo.inheritByDefault() );
506
507 String instantiationStrategy = mojo.instantiationStrategy().id();
508 if ( instantiationStrategy == null )
509 {
510 /* Perhaps the original spelling is there. */
511 instantiationStrategy = mojo.instanciationStrategy().id();
512 }
513 mojoDescriptor.setInstantiationStrategy( instantiationStrategy );
514
515 mojoDescriptor.setAggregator( mojo.aggregator() );
516 mojoDescriptor.setDependencyResolutionRequired( mojo.requiresDependencyResolution().id() );
517 mojoDescriptor.setDependencyCollectionRequired( mojo.requiresDependencyCollection().id() );
518
519 mojoDescriptor.setDirectInvocationOnly( mojo.requiresDirectInvocation() );
520 mojoDescriptor.setDeprecated( mojo.getDeprecated() );
521 mojoDescriptor.setThreadSafe( mojo.threadSafe() );
522
523 ExecuteAnnotationContent execute = findExecuteInParentHierarchy( mojoAnnotatedClass, mojoAnnotatedClasses );
524 if ( execute != null )
525 {
526 mojoDescriptor.setExecuteGoal( execute.goal() );
527 mojoDescriptor.setExecuteLifecycle( execute.lifecycle() );
528 if ( execute.phase() != null )
529 {
530 mojoDescriptor.setExecutePhase( execute.phase().id() );
531 }
532 }
533
534 mojoDescriptor.setExecutionStrategy( mojo.executionStrategy() );
535 // ???
536 //mojoDescriptor.alwaysExecute(mojo.a)
537
538 mojoDescriptor.setGoal( mojo.name() );
539 mojoDescriptor.setOnlineRequired( mojo.requiresOnline() );
540
541 mojoDescriptor.setPhase( mojo.defaultPhase().id() );
542
543 // Parameter annotations
544 Map<String, ParameterAnnotationContent> parameters =
545 getParametersParentHierarchy( mojoAnnotatedClass, new HashMap<String, ParameterAnnotationContent>(),
546 mojoAnnotatedClasses );
547
548 for ( ParameterAnnotationContent parameterAnnotationContent : new TreeSet<ParameterAnnotationContent>(
549 parameters.values() ) )
550 {
551 org.apache.maven.plugin.descriptor.Parameter parameter =
552 new org.apache.maven.plugin.descriptor.Parameter();
553 parameter.setName( parameterAnnotationContent.getFieldName() );
554 parameter.setAlias( parameterAnnotationContent.alias() );
555 parameter.setDefaultValue( parameterAnnotationContent.defaultValue() );
556 parameter.setDeprecated( parameterAnnotationContent.getDeprecated() );
557 parameter.setDescription( parameterAnnotationContent.getDescription() );
558 parameter.setEditable( !parameterAnnotationContent.readonly() );
559 String property = parameterAnnotationContent.property();
560 if ( StringUtils.contains( property, '$' ) || StringUtils.contains( property, '{' )
561 || StringUtils.contains( property, '}' ) )
562 {
563 throw new InvalidParameterException(
564 "Invalid property for parameter '" + parameter.getName() + "', " + "forbidden characters ${}: "
565 + property, null );
566 }
567 parameter.setExpression( StringUtils.isEmpty( property ) ? "" : "${" + property + "}" );
568 parameter.setType( parameterAnnotationContent.getClassName() );
569 parameter.setSince( parameterAnnotationContent.getSince() );
570 parameter.setRequired( parameterAnnotationContent.required() );
571
572 mojoDescriptor.addParameter( parameter );
573 }
574
575 // Component annotations
576 Map<String, ComponentAnnotationContent> components =
577 getComponentsParentHierarchy( mojoAnnotatedClass, new HashMap<String, ComponentAnnotationContent>(),
578 mojoAnnotatedClasses );
579
580 for ( ComponentAnnotationContent componentAnnotationContent : new TreeSet<ComponentAnnotationContent>(
581 components.values() ) )
582 {
583 org.apache.maven.plugin.descriptor.Parameter parameter =
584 new org.apache.maven.plugin.descriptor.Parameter();
585 parameter.setName( componentAnnotationContent.getFieldName() );
586
587 // recognize Maven-injected objects as components annotations instead of parameters
588 String expression = PluginUtils.MAVEN_COMPONENTS.get( componentAnnotationContent.getRoleClassName() );
589 if ( expression == null )
590 {
591 // normal component
592 parameter.setRequirement( new Requirement( componentAnnotationContent.getRoleClassName(),
593 componentAnnotationContent.hint() ) );
594 }
595 else
596 {
597 // not a component but a Maven object to be transformed into an expression/property
598 parameter.setDefaultValue( expression );
599 parameter.setType( componentAnnotationContent.getRoleClassName() );
600 parameter.setRequired( true );
601 }
602 parameter.setDeprecated( componentAnnotationContent.getDeprecated() );
603 parameter.setSince( componentAnnotationContent.getSince() );
604
605 // same behaviour as JavaMojoDescriptorExtractor
606 //parameter.setRequired( ... );
607 parameter.setEditable( false );
608
609 mojoDescriptor.addParameter( parameter );
610 }
611
612 mojoDescriptor.setPluginDescriptor( pluginDescriptor );
613
614 mojoDescriptors.add( mojoDescriptor );
615 }
616 return mojoDescriptors;
617 }
618
619 protected ExecuteAnnotationContent findExecuteInParentHierarchy( MojoAnnotatedClass mojoAnnotatedClass,
620 Map<String, MojoAnnotatedClass> mojoAnnotatedClasses )
621 {
622
623 if ( mojoAnnotatedClass.getExecute() != null )
624 {
625 return mojoAnnotatedClass.getExecute();
626 }
627 String parentClassName = mojoAnnotatedClass.getParentClassName();
628 if ( StringUtils.isEmpty( parentClassName ) )
629 {
630 return null;
631 }
632 MojoAnnotatedClass parent = mojoAnnotatedClasses.get( parentClassName );
633 if ( parent == null )
634 {
635 return null;
636 }
637 return findExecuteInParentHierarchy( parent, mojoAnnotatedClasses );
638 }
639
640
641 protected Map<String, ParameterAnnotationContent> getParametersParentHierarchy(
642 MojoAnnotatedClass mojoAnnotatedClass, Map<String, ParameterAnnotationContent> parameters,
643 Map<String, MojoAnnotatedClass> mojoAnnotatedClasses )
644 {
645 List<ParameterAnnotationContent> parameterAnnotationContents = new ArrayList<ParameterAnnotationContent>();
646
647 parameterAnnotationContents =
648 getParametersParent( mojoAnnotatedClass, parameterAnnotationContents, mojoAnnotatedClasses );
649
650 // move to parent first to build the Map
651 Collections.reverse( parameterAnnotationContents );
652
653 Map<String, ParameterAnnotationContent> map =
654 new HashMap<String, ParameterAnnotationContent>( parameterAnnotationContents.size() );
655
656 for ( ParameterAnnotationContent parameterAnnotationContent : parameterAnnotationContents )
657 {
658 map.put( parameterAnnotationContent.getFieldName(), parameterAnnotationContent );
659 }
660 return map;
661 }
662
663 protected List<ParameterAnnotationContent> getParametersParent( MojoAnnotatedClass mojoAnnotatedClass,
664 List<ParameterAnnotationContent> parameterAnnotationContents,
665 Map<String, MojoAnnotatedClass> mojoAnnotatedClasses )
666 {
667 parameterAnnotationContents.addAll( mojoAnnotatedClass.getParameters().values() );
668 String parentClassName = mojoAnnotatedClass.getParentClassName();
669 if ( parentClassName != null )
670 {
671 MojoAnnotatedClass parent = mojoAnnotatedClasses.get( parentClassName );
672 if ( parent != null )
673 {
674 return getParametersParent( parent, parameterAnnotationContents, mojoAnnotatedClasses );
675 }
676 }
677 return parameterAnnotationContents;
678 }
679
680 protected Map<String, ComponentAnnotationContent> getComponentsParentHierarchy(
681 MojoAnnotatedClass mojoAnnotatedClass, Map<String, ComponentAnnotationContent> components,
682 Map<String, MojoAnnotatedClass> mojoAnnotatedClasses )
683 {
684 List<ComponentAnnotationContent> componentAnnotationContents = new ArrayList<ComponentAnnotationContent>();
685
686 componentAnnotationContents =
687 getComponentParent( mojoAnnotatedClass, componentAnnotationContents, mojoAnnotatedClasses );
688
689 // move to parent first to build the Map
690 Collections.reverse( componentAnnotationContents );
691
692 Map<String, ComponentAnnotationContent> map =
693 new HashMap<String, ComponentAnnotationContent>( componentAnnotationContents.size() );
694
695 for ( ComponentAnnotationContent componentAnnotationContent : componentAnnotationContents )
696 {
697 map.put( componentAnnotationContent.getFieldName(), componentAnnotationContent );
698 }
699 return map;
700 }
701
702 protected List<ComponentAnnotationContent> getComponentParent( MojoAnnotatedClass mojoAnnotatedClass,
703 List<ComponentAnnotationContent> componentAnnotationContents,
704 Map<String, MojoAnnotatedClass> mojoAnnotatedClasses )
705 {
706 componentAnnotationContents.addAll( mojoAnnotatedClass.getComponents().values() );
707 String parentClassName = mojoAnnotatedClass.getParentClassName();
708 if ( parentClassName != null )
709 {
710 MojoAnnotatedClass parent = mojoAnnotatedClasses.get( parentClassName );
711 if ( parent != null )
712 {
713 return getComponentParent( parent, componentAnnotationContents, mojoAnnotatedClasses );
714 }
715 }
716 return componentAnnotationContents;
717 }
718
719 protected MavenProject getFromProjectReferences( Artifact artifact, MavenProject project )
720 {
721 if ( project.getProjectReferences() == null || project.getProjectReferences().isEmpty() )
722 {
723 return null;
724 }
725 @SuppressWarnings( "unchecked" ) Collection<MavenProject> mavenProjects =
726 project.getProjectReferences().values();
727 for ( MavenProject mavenProject : mavenProjects )
728 {
729 if ( StringUtils.equals( mavenProject.getId(), artifact.getId() ) )
730 {
731 return mavenProject;
732 }
733 }
734 return null;
735 }
736
737 }