View Javadoc
1   package org.apache.maven.tools.plugin.scanner;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import javax.inject.Inject;
23  import javax.inject.Named;
24  
25  import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException;
26  import org.apache.maven.plugin.descriptor.MojoDescriptor;
27  import org.apache.maven.tools.plugin.PluginToolsRequest;
28  import org.apache.maven.tools.plugin.extractor.ExtractionException;
29  import org.apache.maven.tools.plugin.extractor.GroupKey;
30  import org.apache.maven.tools.plugin.extractor.MojoDescriptorExtractor;
31  import org.apache.maven.tools.plugin.extractor.MojoDescriptorExtractorComparator;
32  import org.codehaus.plexus.logging.AbstractLogEnabled;
33  import org.codehaus.plexus.logging.Logger;
34  import org.codehaus.plexus.logging.console.ConsoleLogger;
35  import org.codehaus.plexus.util.StringUtils;
36  
37  import java.util.ArrayList;
38  import java.util.Collections;
39  import java.util.HashMap;
40  import java.util.HashSet;
41  import java.util.List;
42  import java.util.Map;
43  import java.util.Set;
44  
45  /**
46   * @author jdcasey
47   */
48  @Named
49  public class DefaultMojoScanner
50      extends AbstractLogEnabled
51      implements MojoScanner
52  {
53  
54      private Map<String, MojoDescriptorExtractor> mojoDescriptorExtractors;
55  
56      /**
57       * The names of the active extractors
58       */
59      private Set<String> activeExtractors;
60  
61      /**
62       * Default constructor
63       *
64       * @param extractors not null
65       */
66      @Inject
67      public DefaultMojoScanner( Map<String, MojoDescriptorExtractor> extractors )
68      {
69          this.mojoDescriptorExtractors = extractors;
70  
71          this.enableLogging( new ConsoleLogger( Logger.LEVEL_INFO, "standalone-scanner-logger" ) );
72      }
73  
74      /**
75       * Empty constructor
76       */
77      public DefaultMojoScanner()
78      {
79          // nop
80      }
81  
82      /**
83       * {@inheritDoc}
84       */
85      @Override
86      public void populatePluginDescriptor( PluginToolsRequest request )
87          throws ExtractionException, InvalidPluginDescriptorException
88      {
89          Logger logger = getLogger();
90  
91          int numMojoDescriptors = 0;
92  
93          List<MojoDescriptorExtractor> orderedExtractors = getOrderedExtractors();
94  
95          logger.debug( "Using " + orderedExtractors.size() + " mojo extractors." );
96  
97          HashMap<String, Integer> groupStats = new HashMap<>();
98  
99          for ( MojoDescriptorExtractor extractor : orderedExtractors )
100         {
101             GroupKey groupKey = extractor.getGroupKey();
102             String extractorId = extractor.getName();
103 
104             logger.debug( "Applying " + extractorId + " mojo extractor" );
105 
106             List<MojoDescriptor> extractorDescriptors = extractor.execute( request );
107 
108             int extractorDescriptorsCount = extractorDescriptors.size();
109 
110             logger.info( extractorId + " mojo extractor found " + extractorDescriptorsCount
111                              + " mojo descriptor" + ( extractorDescriptorsCount > 1 ? "s" : "" ) + "." );
112             numMojoDescriptors += extractorDescriptorsCount;
113 
114             if ( extractor.isDeprecated() &&  extractorDescriptorsCount > 0 )
115             {
116                 logger.warn( "" );
117                 logger.warn( "Deprecated extractor " + extractorId
118                              + " extracted " + extractorDescriptorsCount
119                              + " descriptor" + ( extractorDescriptorsCount > 1 ? "s" : "" )
120                              + ". Upgrade your Mojo definitions." );
121                 if ( GroupKey.JAVA_GROUP.equals( groupKey.getGroup() ) )
122                 {
123                     logger.warn( "You should use Mojo Annotations instead of Javadoc tags." );
124                 }
125                 logger.warn( "" );
126             }
127 
128             if ( groupStats.containsKey( groupKey.getGroup() ) )
129             {
130                 groupStats.put( groupKey.getGroup(),
131                     groupStats.get( groupKey.getGroup() ) + extractorDescriptorsCount );
132             }
133             else
134             {
135                 groupStats.put( groupKey.getGroup(), extractorDescriptorsCount );
136             }
137 
138             for ( MojoDescriptor descriptor : extractorDescriptors )
139             {
140                 logger.debug( "Adding mojo: " + descriptor + " to plugin descriptor." );
141 
142                 descriptor.setPluginDescriptor( request.getPluginDescriptor() );
143 
144                 request.getPluginDescriptor().addMojo( descriptor );
145             }
146         }
147 
148         logger.debug( "Discovered descriptors by groups: " + groupStats );
149 
150         if ( numMojoDescriptors == 0 && !request.isSkipErrorNoDescriptorsFound() )
151         {
152             throw new InvalidPluginDescriptorException(
153                 "No mojo definitions were found for plugin: " + request.getPluginDescriptor().getPluginLookupKey()
154                     + "." );
155         }
156     }
157 
158     /**
159      * Returns a list of extractors sorted by {@link MojoDescriptorExtractor#getGroupKey()}s, never {@code null}.
160      */
161     private List<MojoDescriptorExtractor> getOrderedExtractors() throws ExtractionException
162     {
163         Set<String> extractors = activeExtractors;
164 
165         if ( extractors == null )
166         {
167             extractors = new HashSet<>( mojoDescriptorExtractors.keySet() );
168         }
169 
170         ArrayList<MojoDescriptorExtractor> orderedExtractors = new ArrayList<>();
171         for ( String extractorId : extractors )
172         {
173             MojoDescriptorExtractor extractor = mojoDescriptorExtractors.get( extractorId );
174 
175             if ( extractor == null )
176             {
177                 throw new ExtractionException( "No mojo extractor with '" + extractorId + "' id." );
178             }
179 
180             orderedExtractors.add( extractor );
181         }
182 
183         Collections.sort( orderedExtractors, MojoDescriptorExtractorComparator.INSTANCE );
184 
185         return orderedExtractors;
186     }
187 
188     @Override
189     public void setActiveExtractors( Set<String> extractors )
190     {
191         if ( extractors == null )
192         {
193             this.activeExtractors = null;
194         }
195         else
196         {
197             this.activeExtractors = new HashSet<>();
198 
199             for ( String extractor : extractors )
200             {
201                 if ( StringUtils.isNotEmpty( extractor ) )
202                 {
203                     this.activeExtractors.add( extractor );
204                 }
205             }
206         }
207     }
208 
209 }