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