1 package org.apache.maven.tools.plugin.annotations;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import com.thoughtworks.qdox.JavaDocBuilder;
23 import com.thoughtworks.qdox.model.DocletTag;
24 import com.thoughtworks.qdox.model.JavaClass;
25 import com.thoughtworks.qdox.model.JavaField;
26 import org.apache.maven.artifact.Artifact;
27 import org.apache.maven.artifact.factory.ArtifactFactory;
28 import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
29 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
30 import org.apache.maven.artifact.resolver.ArtifactResolver;
31 import org.apache.maven.plugin.descriptor.DuplicateParameterException;
32 import org.apache.maven.plugin.descriptor.InvalidParameterException;
33 import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException;
34 import org.apache.maven.plugin.descriptor.MojoDescriptor;
35 import org.apache.maven.plugin.descriptor.PluginDescriptor;
36 import org.apache.maven.plugin.descriptor.Requirement;
37 import org.apache.maven.project.MavenProject;
38 import org.apache.maven.tools.plugin.ExtendedMojoDescriptor;
39 import org.apache.maven.tools.plugin.PluginToolsRequest;
40 import org.apache.maven.tools.plugin.annotations.datamodel.ComponentAnnotationContent;
41 import org.apache.maven.tools.plugin.annotations.datamodel.ExecuteAnnotationContent;
42 import org.apache.maven.tools.plugin.annotations.datamodel.MojoAnnotationContent;
43 import org.apache.maven.tools.plugin.annotations.datamodel.ParameterAnnotationContent;
44 import org.apache.maven.tools.plugin.annotations.scanner.MojoAnnotatedClass;
45 import org.apache.maven.tools.plugin.annotations.scanner.MojoAnnotationsScanner;
46 import org.apache.maven.tools.plugin.annotations.scanner.MojoAnnotationsScannerRequest;
47 import org.apache.maven.tools.plugin.extractor.ExtractionException;
48 import org.apache.maven.tools.plugin.extractor.MojoDescriptorExtractor;
49 import org.apache.maven.tools.plugin.util.PluginUtils;
50 import org.codehaus.plexus.archiver.UnArchiver;
51 import org.codehaus.plexus.archiver.manager.ArchiverManager;
52 import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
53 import org.codehaus.plexus.component.annotations.Component;
54 import org.codehaus.plexus.logging.AbstractLogEnabled;
55 import org.codehaus.plexus.util.StringUtils;
56
57 import java.io.File;
58 import java.util.ArrayList;
59 import java.util.Arrays;
60 import java.util.Collection;
61 import java.util.Collections;
62 import java.util.HashMap;
63 import java.util.HashSet;
64 import java.util.List;
65 import java.util.Map;
66 import java.util.Set;
67 import java.util.TreeMap;
68 import java.util.TreeSet;
69
70
71
72
73
74
75
76
77 @Component( role = MojoDescriptorExtractor.class, hint = "java-annotations" )
78 public class JavaAnnotationsMojoDescriptorExtractor
79 extends AbstractLogEnabled
80 implements MojoDescriptorExtractor
81 {
82
83 @org.codehaus.plexus.component.annotations.Requirement
84 private MojoAnnotationsScanner mojoAnnotationsScanner;
85
86 @org.codehaus.plexus.component.annotations.Requirement
87 private ArtifactResolver artifactResolver;
88
89 @org.codehaus.plexus.component.annotations.Requirement
90 private ArtifactFactory artifactFactory;
91
92 @org.codehaus.plexus.component.annotations.Requirement
93 private ArchiverManager archiverManager;
94
95 public List<MojoDescriptor> execute( PluginToolsRequest request )
96 throws ExtractionException, InvalidPluginDescriptorException
97 {
98 Map<String, MojoAnnotatedClass> mojoAnnotatedClasses = scanAnnotations( request );
99
100 Map<String, JavaClass> javaClassesMap = scanJavadoc( request, mojoAnnotatedClasses.values() );
101
102 populateDataFromJavadoc( mojoAnnotatedClasses, javaClassesMap );
103
104 return toMojoDescriptors( mojoAnnotatedClasses, request.getPluginDescriptor() );
105 }
106
107 private Map<String, MojoAnnotatedClass> scanAnnotations( PluginToolsRequest request )
108 throws ExtractionException
109 {
110 MojoAnnotationsScannerRequest mojoAnnotationsScannerRequest = new MojoAnnotationsScannerRequest();
111
112 File output = new File( request.getProject().getBuild().getOutputDirectory() );
113 mojoAnnotationsScannerRequest.setClassesDirectories( Arrays.asList( output ) );
114
115 mojoAnnotationsScannerRequest.setDependencies( request.getDependencies() );
116
117 mojoAnnotationsScannerRequest.setProject( request.getProject() );
118
119 return mojoAnnotationsScanner.scan( mojoAnnotationsScannerRequest );
120 }
121
122 private Map<String, JavaClass> scanJavadoc( PluginToolsRequest request,
123 Collection<MojoAnnotatedClass> mojoAnnotatedClasses )
124 throws ExtractionException
125 {
126
127
128 List<MavenProject> mavenProjects = new ArrayList<MavenProject>();
129
130
131 Set<Artifact> externalArtifacts = new HashSet<Artifact>();
132
133 for ( MojoAnnotatedClass mojoAnnotatedClass : mojoAnnotatedClasses )
134 {
135 if ( StringUtils.equals( mojoAnnotatedClass.getArtifact().getArtifactId(),
136 request.getProject().getArtifact().getArtifactId() ) )
137 {
138 continue;
139 }
140
141 if ( !isMojoAnnnotatedClassCandidate( mojoAnnotatedClass ) )
142 {
143
144 continue;
145 }
146
147 MavenProject mavenProject =
148 getFromProjectReferences( mojoAnnotatedClass.getArtifact(), request.getProject() );
149
150 if ( mavenProject != null )
151 {
152 mavenProjects.add( mavenProject );
153 }
154 else
155 {
156 externalArtifacts.add( mojoAnnotatedClass.getArtifact() );
157 }
158 }
159
160 Map<String, JavaClass> javaClassesMap = new HashMap<String, JavaClass>();
161
162
163 for ( Artifact artifact : externalArtifacts )
164 {
165
166 if ( StringUtils.equalsIgnoreCase( "tests", artifact.getClassifier() ) )
167 {
168 javaClassesMap.putAll( discoverClassesFromSourcesJar( artifact, request, "test-sources" ) );
169 }
170 else
171 {
172 javaClassesMap.putAll( discoverClassesFromSourcesJar( artifact, request, "sources" ) );
173 }
174
175 }
176
177 for ( MavenProject mavenProject : mavenProjects )
178 {
179 javaClassesMap.putAll( discoverClasses( request.getEncoding(), mavenProject ) );
180 }
181
182 javaClassesMap.putAll( discoverClasses( request ) );
183
184 return javaClassesMap;
185 }
186
187 private boolean isMojoAnnnotatedClassCandidate( MojoAnnotatedClass mojoAnnotatedClass )
188 {
189 return mojoAnnotatedClass != null && mojoAnnotatedClass.hasAnnotations();
190 }
191
192 protected Map<String, JavaClass> discoverClassesFromSourcesJar( Artifact artifact, PluginToolsRequest request,
193 String classifier )
194 throws ExtractionException
195 {
196 try
197 {
198 Artifact sourcesArtifact =
199 artifactFactory.createArtifactWithClassifier( artifact.getGroupId(), artifact.getArtifactId(),
200 artifact.getVersion(), artifact.getType(), classifier );
201
202 artifactResolver.resolve( sourcesArtifact, request.getRemoteRepos(), request.getLocal() );
203
204 if ( sourcesArtifact.getFile() == null || !sourcesArtifact.getFile().exists() )
205 {
206
207 return Collections.emptyMap();
208 }
209
210
211 File extractDirectory = new File( request.getProject().getBuild().getDirectory(),
212 "maven-plugin-plugin-sources/" + sourcesArtifact.getGroupId() + "/"
213 + sourcesArtifact.getArtifactId() + "/" + sourcesArtifact.getVersion()
214 + "/" + sourcesArtifact.getClassifier() );
215 extractDirectory.mkdirs();
216
217 UnArchiver unArchiver = archiverManager.getUnArchiver( "jar" );
218 unArchiver.setSourceFile( sourcesArtifact.getFile() );
219 unArchiver.setDestDirectory( extractDirectory );
220 unArchiver.extract();
221
222 return discoverClasses( request.getEncoding(), Arrays.asList( extractDirectory ) );
223 }
224 catch ( ArtifactResolutionException e )
225 {
226 throw new ExtractionException( e.getMessage(), e );
227 }
228 catch ( ArtifactNotFoundException e )
229 {
230
231 getLogger().debug( "skip ArtifactNotFoundException:" + e.getMessage() );
232 getLogger().warn(
233 "Unable to get sources artifact for " + artifact.getGroupId() + ":" + artifact.getArtifactId() + ":"
234 + artifact.getVersion() + ". Some javadoc tags (@since, @deprecated and comments) won't be used" );
235 return Collections.emptyMap();
236 }
237 catch ( NoSuchArchiverException e )
238 {
239 throw new ExtractionException( e.getMessage(), e );
240 }
241 }
242
243
244
245
246
247
248
249 protected void populateDataFromJavadoc( Map<String, MojoAnnotatedClass> mojoAnnotatedClasses,
250 Map<String, JavaClass> javaClassesMap )
251 {
252
253 for ( Map.Entry<String, MojoAnnotatedClass> entry : mojoAnnotatedClasses.entrySet() )
254 {
255 JavaClass javaClass = javaClassesMap.get( entry.getKey() );
256 if ( javaClass == null )
257 {
258 continue;
259 }
260
261
262 MojoAnnotationContent mojoAnnotationContent = entry.getValue().getMojo();
263 if ( mojoAnnotationContent != null )
264 {
265 mojoAnnotationContent.setDescription( javaClass.getComment() );
266
267 DocletTag since = findInClassHierarchy( javaClass, "since" );
268 if ( since != null )
269 {
270 mojoAnnotationContent.setSince( since.getValue() );
271 }
272
273 DocletTag deprecated = findInClassHierarchy( javaClass, "deprecated" );
274 if ( deprecated != null )
275 {
276 mojoAnnotationContent.setDeprecated( deprecated.getValue() );
277 }
278 }
279
280 Map<String, JavaField> fieldsMap = extractFieldParameterTags( javaClass, javaClassesMap );
281
282
283 Map<String, ParameterAnnotationContent> parameters =
284 getParametersParentHierarchy( entry.getValue(), new HashMap<String, ParameterAnnotationContent>(),
285 mojoAnnotatedClasses );
286 for ( Map.Entry<String, ParameterAnnotationContent> parameter : new TreeMap<String, ParameterAnnotationContent>(
287 parameters ).entrySet() )
288 {
289 JavaField javaField = fieldsMap.get( parameter.getKey() );
290 if ( javaField == null )
291 {
292 continue;
293 }
294
295 ParameterAnnotationContent parameterAnnotationContent = parameter.getValue();
296 parameterAnnotationContent.setDescription( javaField.getComment() );
297
298 DocletTag deprecated = javaField.getTagByName( "deprecated" );
299 if ( deprecated != null )
300 {
301 parameterAnnotationContent.setDeprecated( deprecated.getValue() );
302 }
303
304 DocletTag since = javaField.getTagByName( "since" );
305 if ( since != null )
306 {
307 parameterAnnotationContent.setSince( since.getValue() );
308 }
309 }
310
311
312 for ( Map.Entry<String, ComponentAnnotationContent> component : entry.getValue().getComponents().entrySet() )
313 {
314 JavaField javaField = fieldsMap.get( component.getKey() );
315 if ( javaField == null )
316 {
317 continue;
318 }
319
320 ComponentAnnotationContent componentAnnotationContent = component.getValue();
321 componentAnnotationContent.setDescription( javaField.getComment() );
322
323 DocletTag deprecated = javaField.getTagByName( "deprecated" );
324 if ( deprecated != null )
325 {
326 componentAnnotationContent.setDeprecated( deprecated.getValue() );
327 }
328
329 DocletTag since = javaField.getTagByName( "since" );
330 if ( since != null )
331 {
332 componentAnnotationContent.setSince( since.getValue() );
333 }
334 }
335
336 }
337
338 }
339
340
341
342
343
344
345 private DocletTag findInClassHierarchy( JavaClass javaClass, String tagName )
346 {
347 DocletTag tag = javaClass.getTagByName( tagName );
348
349 if ( tag == null )
350 {
351 JavaClass superClass = javaClass.getSuperJavaClass();
352
353 if ( superClass != null )
354 {
355 tag = findInClassHierarchy( superClass, tagName );
356 }
357 }
358
359 return tag;
360 }
361
362
363
364
365
366
367
368 private Map<String, JavaField> extractFieldParameterTags( JavaClass javaClass,
369 Map<String, JavaClass> javaClassesMap )
370 {
371 Map<String, JavaField> rawParams = new TreeMap<String, com.thoughtworks.qdox.model.JavaField>();
372
373
374
375 JavaClass superClass = javaClass.getSuperJavaClass();
376
377 if ( superClass != null )
378 {
379 if ( superClass.getFields().length > 0 )
380 {
381 rawParams = extractFieldParameterTags( superClass, javaClassesMap );
382 }
383
384 superClass = javaClassesMap.get( superClass.getFullyQualifiedName() );
385 if ( superClass != null )
386 {
387 rawParams = extractFieldParameterTags( superClass, javaClassesMap );
388 }
389 }
390 else
391 {
392
393 rawParams = new TreeMap<String, JavaField>();
394 }
395
396 JavaField[] classFields = javaClass.getFields();
397
398 if ( classFields != null )
399 {
400 for ( JavaField field : classFields )
401 {
402 rawParams.put( field.getName(), field );
403 }
404 }
405 return rawParams;
406 }
407
408 protected Map<String, JavaClass> discoverClasses( final PluginToolsRequest request )
409 {
410 return discoverClasses( request.getEncoding(), request.getProject() );
411 }
412
413 @SuppressWarnings( "unchecked" )
414 protected Map<String, JavaClass> discoverClasses( final String encoding, final MavenProject project )
415 {
416 List<File> sources = new ArrayList<File>();
417
418 for ( String source : (List<String>) project.getCompileSourceRoots() )
419 {
420 sources.add( new File( source ) );
421 }
422
423
424 File generatedPlugin = new File( project.getBasedir(), "target/generated-sources/plugin" );
425 if ( !project.getCompileSourceRoots().contains( generatedPlugin.getAbsolutePath() )
426 && generatedPlugin.exists() )
427 {
428 sources.add( generatedPlugin );
429 }
430
431 return discoverClasses( encoding, sources );
432 }
433
434 protected Map<String, JavaClass> discoverClasses( final String encoding, List<File> sourceDirectories )
435 {
436 JavaDocBuilder builder = new JavaDocBuilder();
437 builder.setEncoding( encoding );
438
439 for ( File source : sourceDirectories )
440 {
441 builder.addSourceTree( source );
442 }
443
444 JavaClass[] javaClasses = builder.getClasses();
445
446 if ( javaClasses == null || javaClasses.length < 1 )
447 {
448 return Collections.emptyMap();
449 }
450
451 Map<String, JavaClass> javaClassMap = new HashMap<String, JavaClass>( javaClasses.length );
452
453 for ( JavaClass javaClass : javaClasses )
454 {
455 javaClassMap.put( javaClass.getFullyQualifiedName(), javaClass );
456 }
457
458 return javaClassMap;
459 }
460
461 private List<MojoDescriptor> toMojoDescriptors( Map<String, MojoAnnotatedClass> mojoAnnotatedClasses,
462 PluginDescriptor pluginDescriptor )
463 throws DuplicateParameterException, InvalidParameterException
464 {
465 List<MojoDescriptor> mojoDescriptors = new ArrayList<MojoDescriptor>( mojoAnnotatedClasses.size() );
466 for ( MojoAnnotatedClass mojoAnnotatedClass : mojoAnnotatedClasses.values() )
467 {
468
469 if ( mojoAnnotatedClass.getMojo() == null )
470 {
471 continue;
472 }
473
474 ExtendedMojoDescriptor mojoDescriptor = new ExtendedMojoDescriptor();
475
476
477
478 mojoDescriptor.setImplementation( mojoAnnotatedClass.getClassName() );
479 mojoDescriptor.setLanguage( "java" );
480
481 MojoAnnotationContent mojo = mojoAnnotatedClass.getMojo();
482
483 mojoDescriptor.setDescription( mojo.getDescription() );
484 mojoDescriptor.setSince( mojo.getSince() );
485 mojo.setDeprecated( mojo.getDeprecated() );
486
487 mojoDescriptor.setProjectRequired( mojo.requiresProject() );
488
489 mojoDescriptor.setRequiresReports( mojo.requiresReports() );
490
491 mojoDescriptor.setComponentConfigurator( mojo.configurator() );
492
493 mojoDescriptor.setInheritedByDefault( mojo.inheritByDefault() );
494
495 mojoDescriptor.setInstantiationStrategy( mojo.instantiationStrategy().id() );
496
497 mojoDescriptor.setAggregator( mojo.aggregator() );
498 mojoDescriptor.setDependencyResolutionRequired( mojo.requiresDependencyResolution().id() );
499 mojoDescriptor.setDependencyCollectionRequired( mojo.requiresDependencyCollection().id() );
500
501 mojoDescriptor.setDirectInvocationOnly( mojo.requiresDirectInvocation() );
502 mojoDescriptor.setDeprecated( mojo.getDeprecated() );
503 mojoDescriptor.setThreadSafe( mojo.threadSafe() );
504
505 ExecuteAnnotationContent execute = findExecuteInParentHierarchy( mojoAnnotatedClass, mojoAnnotatedClasses );
506 if ( execute != null )
507 {
508 mojoDescriptor.setExecuteGoal( execute.goal() );
509 mojoDescriptor.setExecuteLifecycle( execute.lifecycle() );
510 if ( execute.phase() != null )
511 {
512 mojoDescriptor.setExecutePhase( execute.phase().id() );
513 }
514 }
515
516 mojoDescriptor.setExecutionStrategy( mojo.executionStrategy() );
517
518
519
520 mojoDescriptor.setGoal( mojo.name() );
521 mojoDescriptor.setOnlineRequired( mojo.requiresOnline() );
522
523 mojoDescriptor.setPhase( mojo.defaultPhase().id() );
524
525
526 Map<String, ParameterAnnotationContent> parameters =
527 getParametersParentHierarchy( mojoAnnotatedClass, new HashMap<String, ParameterAnnotationContent>(),
528 mojoAnnotatedClasses );
529
530 for ( ParameterAnnotationContent parameterAnnotationContent : new TreeSet<ParameterAnnotationContent>(
531 parameters.values() ) )
532 {
533 org.apache.maven.plugin.descriptor.Parameter parameter =
534 new org.apache.maven.plugin.descriptor.Parameter();
535 String name =
536 StringUtils.isEmpty( parameterAnnotationContent.name() ) ? parameterAnnotationContent.getFieldName()
537 : parameterAnnotationContent.name();
538 parameter.setName( name );
539 parameter.setAlias( parameterAnnotationContent.alias() );
540 parameter.setDefaultValue( parameterAnnotationContent.defaultValue() );
541 parameter.setDeprecated( parameterAnnotationContent.getDeprecated() );
542 parameter.setDescription( parameterAnnotationContent.getDescription() );
543 parameter.setEditable( !parameterAnnotationContent.readonly() );
544 String property = parameterAnnotationContent.property();
545 if ( StringUtils.contains( property, '$' ) || StringUtils.contains( property, '{' )
546 || StringUtils.contains( property, '}' ) )
547 {
548 throw new InvalidParameterException(
549 "Invalid property for parameter '" + parameter.getName() + "', " + "forbidden characters ${}: "
550 + property, null );
551 }
552 parameter.setExpression( StringUtils.isEmpty( property ) ? "" : "${" + property + "}" );
553 parameter.setType( parameterAnnotationContent.getClassName() );
554 parameter.setSince( parameterAnnotationContent.getSince() );
555 parameter.setRequired( parameterAnnotationContent.required() );
556
557 mojoDescriptor.addParameter( parameter );
558 }
559
560
561 Map<String, ComponentAnnotationContent> components =
562 getComponentsParentHierarchy( mojoAnnotatedClass, new HashMap<String, ComponentAnnotationContent>(),
563 mojoAnnotatedClasses );
564
565 for ( ComponentAnnotationContent componentAnnotationContent : new TreeSet<ComponentAnnotationContent>(
566 components.values() ) )
567 {
568 org.apache.maven.plugin.descriptor.Parameter parameter =
569 new org.apache.maven.plugin.descriptor.Parameter();
570 parameter.setName( componentAnnotationContent.getFieldName() );
571
572
573 String expression = PluginUtils.MAVEN_COMPONENTS.get( componentAnnotationContent.getRoleClassName() );
574 if ( expression == null )
575 {
576
577 parameter.setRequirement( new Requirement( componentAnnotationContent.getRoleClassName(),
578 componentAnnotationContent.hint() ) );
579 }
580 else
581 {
582
583 getLogger().warn( "Deprecated @component for " + parameter.getName() + " field in "
584 + mojoAnnotatedClass.getClassName() + "."
585 + ": replace with @parameter name=\"" + expression + "\" @readonly" );
586 parameter.setDefaultValue( expression );
587 parameter.setType( componentAnnotationContent.getRoleClassName() );
588 parameter.setRequired( true );
589 }
590 parameter.setDeprecated( componentAnnotationContent.getDeprecated() );
591 parameter.setSince( componentAnnotationContent.getSince() );
592
593
594
595 parameter.setEditable( false );
596
597 mojoDescriptor.addParameter( parameter );
598 }
599
600 mojoDescriptor.setPluginDescriptor( pluginDescriptor );
601
602 mojoDescriptors.add( mojoDescriptor );
603 }
604 return mojoDescriptors;
605 }
606
607 protected ExecuteAnnotationContent findExecuteInParentHierarchy( MojoAnnotatedClass mojoAnnotatedClass,
608 Map<String, MojoAnnotatedClass> mojoAnnotatedClasses )
609 {
610 if ( mojoAnnotatedClass.getExecute() != null )
611 {
612 return mojoAnnotatedClass.getExecute();
613 }
614 String parentClassName = mojoAnnotatedClass.getParentClassName();
615 if ( StringUtils.isEmpty( parentClassName ) )
616 {
617 return null;
618 }
619 MojoAnnotatedClass parent = mojoAnnotatedClasses.get( parentClassName );
620 if ( parent == null )
621 {
622 return null;
623 }
624 return findExecuteInParentHierarchy( parent, mojoAnnotatedClasses );
625 }
626
627
628 protected Map<String, ParameterAnnotationContent> getParametersParentHierarchy(
629 MojoAnnotatedClass mojoAnnotatedClass, Map<String, ParameterAnnotationContent> parameters,
630 Map<String, MojoAnnotatedClass> mojoAnnotatedClasses )
631 {
632 List<ParameterAnnotationContent> parameterAnnotationContents = new ArrayList<ParameterAnnotationContent>();
633
634 parameterAnnotationContents =
635 getParametersParent( mojoAnnotatedClass, parameterAnnotationContents, mojoAnnotatedClasses );
636
637
638 Collections.reverse( parameterAnnotationContents );
639
640 Map<String, ParameterAnnotationContent> map =
641 new HashMap<String, ParameterAnnotationContent>( parameterAnnotationContents.size() );
642
643 for ( ParameterAnnotationContent parameterAnnotationContent : parameterAnnotationContents )
644 {
645 map.put( parameterAnnotationContent.getFieldName(), parameterAnnotationContent );
646 }
647 return map;
648 }
649
650 protected List<ParameterAnnotationContent> getParametersParent( MojoAnnotatedClass mojoAnnotatedClass,
651 List<ParameterAnnotationContent> parameterAnnotationContents,
652 Map<String, MojoAnnotatedClass> mojoAnnotatedClasses )
653 {
654 parameterAnnotationContents.addAll( mojoAnnotatedClass.getParameters().values() );
655 String parentClassName = mojoAnnotatedClass.getParentClassName();
656 if ( parentClassName != null )
657 {
658 MojoAnnotatedClass parent = mojoAnnotatedClasses.get( parentClassName );
659 if ( parent != null )
660 {
661 return getParametersParent( parent, parameterAnnotationContents, mojoAnnotatedClasses );
662 }
663 }
664 return parameterAnnotationContents;
665 }
666
667 protected Map<String, ComponentAnnotationContent> getComponentsParentHierarchy(
668 MojoAnnotatedClass mojoAnnotatedClass, Map<String, ComponentAnnotationContent> components,
669 Map<String, MojoAnnotatedClass> mojoAnnotatedClasses )
670 {
671 List<ComponentAnnotationContent> componentAnnotationContents = new ArrayList<ComponentAnnotationContent>();
672
673 componentAnnotationContents =
674 getComponentParent( mojoAnnotatedClass, componentAnnotationContents, mojoAnnotatedClasses );
675
676
677 Collections.reverse( componentAnnotationContents );
678
679 Map<String, ComponentAnnotationContent> map =
680 new HashMap<String, ComponentAnnotationContent>( componentAnnotationContents.size() );
681
682 for ( ComponentAnnotationContent componentAnnotationContent : componentAnnotationContents )
683 {
684 map.put( componentAnnotationContent.getFieldName(), componentAnnotationContent );
685 }
686 return map;
687 }
688
689 protected List<ComponentAnnotationContent> getComponentParent( MojoAnnotatedClass mojoAnnotatedClass,
690 List<ComponentAnnotationContent> componentAnnotationContents,
691 Map<String, MojoAnnotatedClass> mojoAnnotatedClasses )
692 {
693 componentAnnotationContents.addAll( mojoAnnotatedClass.getComponents().values() );
694 String parentClassName = mojoAnnotatedClass.getParentClassName();
695 if ( parentClassName != null )
696 {
697 MojoAnnotatedClass parent = mojoAnnotatedClasses.get( parentClassName );
698 if ( parent != null )
699 {
700 return getComponentParent( parent, componentAnnotationContents, mojoAnnotatedClasses );
701 }
702 }
703 return componentAnnotationContents;
704 }
705
706 protected MavenProject getFromProjectReferences( Artifact artifact, MavenProject project )
707 {
708 if ( project.getProjectReferences() == null || project.getProjectReferences().isEmpty() )
709 {
710 return null;
711 }
712 @SuppressWarnings( "unchecked" ) Collection<MavenProject> mavenProjects =
713 project.getProjectReferences().values();
714 for ( MavenProject mavenProject : mavenProjects )
715 {
716 if ( StringUtils.equals( mavenProject.getId(), artifact.getId() ) )
717 {
718 return mavenProject;
719 }
720 }
721 return null;
722 }
723
724 }