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