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 mojoDescriptor.setInstantiationStrategy( mojo.instantiationStrategy().id() );
508
509 mojoDescriptor.setAggregator( mojo.aggregator() );
510 mojoDescriptor.setDependencyResolutionRequired( mojo.requiresDependencyResolution().id() );
511 mojoDescriptor.setDependencyCollectionRequired( mojo.requiresDependencyCollection().id() );
512
513 mojoDescriptor.setDirectInvocationOnly( mojo.requiresDirectInvocation() );
514 mojoDescriptor.setDeprecated( mojo.getDeprecated() );
515 mojoDescriptor.setThreadSafe( mojo.threadSafe() );
516
517 ExecuteAnnotationContent execute = findExecuteInParentHierarchy( mojoAnnotatedClass, mojoAnnotatedClasses );
518 if ( execute != null )
519 {
520 mojoDescriptor.setExecuteGoal( execute.goal() );
521 mojoDescriptor.setExecuteLifecycle( execute.lifecycle() );
522 mojoDescriptor.setExecutePhase( execute.phase().id() );
523 }
524
525 mojoDescriptor.setExecutionStrategy( mojo.executionStrategy() );
526 // ???
527 //mojoDescriptor.alwaysExecute(mojo.a)
528
529 mojoDescriptor.setGoal( mojo.name() );
530 mojoDescriptor.setOnlineRequired( mojo.requiresOnline() );
531
532 mojoDescriptor.setPhase( mojo.defaultPhase().id() );
533
534 Map<String, ParameterAnnotationContent> parameters =
535 getParametersParentHierarchy( mojoAnnotatedClass, new HashMap<String, ParameterAnnotationContent>(),
536 mojoAnnotatedClasses );
537
538 for ( ParameterAnnotationContent parameterAnnotationContent : new TreeSet<ParameterAnnotationContent>(
539 parameters.values() ) )
540 {
541 org.apache.maven.plugin.descriptor.Parameter parameter =
542 new org.apache.maven.plugin.descriptor.Parameter();
543 parameter.setName( parameterAnnotationContent.getFieldName() );
544 parameter.setAlias( parameterAnnotationContent.alias() );
545 parameter.setDefaultValue( parameterAnnotationContent.defaultValue() );
546 parameter.setDeprecated( parameterAnnotationContent.getDeprecated() );
547 parameter.setDescription( parameterAnnotationContent.getDescription() );
548 parameter.setEditable( !parameterAnnotationContent.readonly() );
549 String property = parameterAnnotationContent.property();
550 if ( StringUtils.contains( property, '$' ) || StringUtils.contains( property, '{' )
551 || StringUtils.contains( property, '}' ) )
552 {
553 throw new InvalidParameterException(
554 "Invalid property for parameter '" + parameter.getName() + "', " + "forbidden characters ${}: "
555 + property, null );
556 }
557 parameter.setExpression( StringUtils.isEmpty( property ) ? "" : "${" + property + "}" );
558 parameter.setType( parameterAnnotationContent.getClassName() );
559 parameter.setSince( parameterAnnotationContent.getSince() );
560 parameter.setRequired( parameterAnnotationContent.required() );
561
562 mojoDescriptor.addParameter( parameter );
563 }
564
565 Map<String, ComponentAnnotationContent> components =
566 getComponentsParentHierarchy( mojoAnnotatedClass, new HashMap<String, ComponentAnnotationContent>(),
567 mojoAnnotatedClasses );
568
569 for ( ComponentAnnotationContent componentAnnotationContent : new TreeSet<ComponentAnnotationContent>(
570 components.values() ) )
571 {
572 org.apache.maven.plugin.descriptor.Parameter parameter =
573 new org.apache.maven.plugin.descriptor.Parameter();
574 parameter.setName( componentAnnotationContent.getFieldName() );
575
576 String expression = PluginUtils.MAVEN_COMPONENTS.get( componentAnnotationContent.getRoleClassName() );
577 if ( expression == null )
578 {
579 parameter.setRequirement( new Requirement( componentAnnotationContent.getRoleClassName(),
580 componentAnnotationContent.hint() ) );
581 }
582 else
583 {
584 parameter.setDefaultValue( expression );
585 parameter.setImplementation( componentAnnotationContent.getRoleClassName() );
586 parameter.setType( componentAnnotationContent.getRoleClassName() );
587 }
588 parameter.setDeprecated( componentAnnotationContent.getDeprecated() );
589 parameter.setSince( componentAnnotationContent.getSince() );
590
591 // same behaviour as JavaMojoDescriptorExtractor
592 //parameter.setRequired( ... );
593 parameter.setEditable( false );
594 mojoDescriptor.addParameter( parameter );
595 }
596
597 mojoDescriptor.setPluginDescriptor( pluginDescriptor );
598
599 mojoDescriptors.add( mojoDescriptor );
600 }
601 return mojoDescriptors;
602 }
603
604 protected ExecuteAnnotationContent findExecuteInParentHierarchy( MojoAnnotatedClass mojoAnnotatedClass,
605 Map<String, MojoAnnotatedClass> mojoAnnotatedClasses )
606 {
607
608 if ( mojoAnnotatedClass.getExecute() != null )
609 {
610 return mojoAnnotatedClass.getExecute();
611 }
612 String parentClassName = mojoAnnotatedClass.getParentClassName();
613 if ( StringUtils.isEmpty( parentClassName ) )
614 {
615 return null;
616 }
617 MojoAnnotatedClass parent = mojoAnnotatedClasses.get( parentClassName );
618 if ( parent == null )
619 {
620 return null;
621 }
622 return findExecuteInParentHierarchy( parent, mojoAnnotatedClasses );
623 }
624
625
626 protected Map<String, ParameterAnnotationContent> getParametersParentHierarchy(
627 MojoAnnotatedClass mojoAnnotatedClass, Map<String, ParameterAnnotationContent> parameters,
628 Map<String, MojoAnnotatedClass> mojoAnnotatedClasses )
629 {
630 List<ParameterAnnotationContent> parameterAnnotationContents = new ArrayList<ParameterAnnotationContent>();
631
632 parameterAnnotationContents =
633 getParametersParent( mojoAnnotatedClass, parameterAnnotationContents, mojoAnnotatedClasses );
634
635 // move to parent first to build the Map
636 Collections.reverse( parameterAnnotationContents );
637
638 Map<String, ParameterAnnotationContent> map =
639 new HashMap<String, ParameterAnnotationContent>( parameterAnnotationContents.size() );
640
641 for ( ParameterAnnotationContent parameterAnnotationContent : parameterAnnotationContents )
642 {
643 map.put( parameterAnnotationContent.getFieldName(), parameterAnnotationContent );
644 }
645 return map;
646 }
647
648 protected List<ParameterAnnotationContent> getParametersParent( MojoAnnotatedClass mojoAnnotatedClass,
649 List<ParameterAnnotationContent> parameterAnnotationContents,
650 Map<String, MojoAnnotatedClass> mojoAnnotatedClasses )
651 {
652 parameterAnnotationContents.addAll( mojoAnnotatedClass.getParameters().values() );
653 String parentClassName = mojoAnnotatedClass.getParentClassName();
654 if ( parentClassName != null )
655 {
656 MojoAnnotatedClass parent = mojoAnnotatedClasses.get( parentClassName );
657 if ( parent != null )
658 {
659 return getParametersParent( parent, parameterAnnotationContents, mojoAnnotatedClasses );
660 }
661 }
662 return parameterAnnotationContents;
663 }
664
665 protected Map<String, ComponentAnnotationContent> getComponentsParentHierarchy(
666 MojoAnnotatedClass mojoAnnotatedClass, Map<String, ComponentAnnotationContent> components,
667 Map<String, MojoAnnotatedClass> mojoAnnotatedClasses )
668 {
669 List<ComponentAnnotationContent> componentAnnotationContents = new ArrayList<ComponentAnnotationContent>();
670
671 componentAnnotationContents =
672 getComponentParent( mojoAnnotatedClass, componentAnnotationContents, mojoAnnotatedClasses );
673
674 // move to parent first to build the Map
675 Collections.reverse( componentAnnotationContents );
676
677 Map<String, ComponentAnnotationContent> map =
678 new HashMap<String, ComponentAnnotationContent>( componentAnnotationContents.size() );
679
680 for ( ComponentAnnotationContent componentAnnotationContent : componentAnnotationContents )
681 {
682 map.put( componentAnnotationContent.getFieldName(), componentAnnotationContent );
683 }
684 return map;
685 }
686
687 protected List<ComponentAnnotationContent> getComponentParent( MojoAnnotatedClass mojoAnnotatedClass,
688 List<ComponentAnnotationContent> componentAnnotationContents,
689 Map<String, MojoAnnotatedClass> mojoAnnotatedClasses )
690 {
691 componentAnnotationContents.addAll( mojoAnnotatedClass.getComponents().values() );
692 String parentClassName = mojoAnnotatedClass.getParentClassName();
693 if ( parentClassName != null )
694 {
695 MojoAnnotatedClass parent = mojoAnnotatedClasses.get( parentClassName );
696 if ( parent != null )
697 {
698 return getComponentParent( parent, componentAnnotationContents, mojoAnnotatedClasses );
699 }
700 }
701 return componentAnnotationContents;
702 }
703
704 protected MavenProject getFromProjectReferences( Artifact artifact, MavenProject project )
705 {
706 if ( project.getProjectReferences() == null || project.getProjectReferences().isEmpty() )
707 {
708 return null;
709 }
710 @SuppressWarnings( "unchecked" ) Collection<MavenProject> mavenProjects =
711 project.getProjectReferences().values();
712 for ( MavenProject mavenProject : mavenProjects )
713 {
714 if ( StringUtils.equals( mavenProject.getId(), artifact.getId() ) )
715 {
716 return mavenProject;
717 }
718 }
719 return null;
720 }
721
722 }