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