001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.maven.tools.plugin.scanner; 020 021import javax.inject.Inject; 022import javax.inject.Named; 023 024import java.util.ArrayList; 025import java.util.Collections; 026import java.util.HashMap; 027import java.util.HashSet; 028import java.util.List; 029import java.util.Map; 030import java.util.Set; 031 032import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException; 033import org.apache.maven.plugin.descriptor.MojoDescriptor; 034import org.apache.maven.tools.plugin.PluginToolsRequest; 035import org.apache.maven.tools.plugin.extractor.ExtractionException; 036import org.apache.maven.tools.plugin.extractor.GroupKey; 037import org.apache.maven.tools.plugin.extractor.MojoDescriptorExtractor; 038import org.apache.maven.tools.plugin.extractor.MojoDescriptorExtractorComparator; 039import org.codehaus.plexus.logging.AbstractLogEnabled; 040import org.codehaus.plexus.logging.Logger; 041import org.codehaus.plexus.logging.console.ConsoleLogger; 042 043/** 044 * @author jdcasey 045 */ 046@Named 047public class DefaultMojoScanner extends AbstractLogEnabled implements MojoScanner { 048 049 private Map<String, MojoDescriptorExtractor> mojoDescriptorExtractors; 050 051 /** 052 * The names of the active extractors 053 */ 054 private Set<String> activeExtractors; 055 056 /** 057 * Default constructor 058 * 059 * @param extractors not null 060 */ 061 @Inject 062 public DefaultMojoScanner(Map<String, MojoDescriptorExtractor> extractors) { 063 this.mojoDescriptorExtractors = extractors; 064 065 this.enableLogging(new ConsoleLogger(Logger.LEVEL_INFO, "standalone-scanner-logger")); 066 } 067 068 /** 069 * Empty constructor 070 */ 071 public DefaultMojoScanner() { 072 // nop 073 } 074 075 /** 076 * {@inheritDoc} 077 */ 078 @Override 079 public void populatePluginDescriptor(PluginToolsRequest request) 080 throws ExtractionException, InvalidPluginDescriptorException { 081 Logger logger = getLogger(); 082 083 int numMojoDescriptors = 0; 084 085 List<MojoDescriptorExtractor> orderedExtractors = getOrderedExtractors(); 086 087 logger.debug("Using " + orderedExtractors.size() + " mojo extractors."); 088 089 HashMap<String, Integer> groupStats = new HashMap<>(); 090 091 for (MojoDescriptorExtractor extractor : orderedExtractors) { 092 GroupKey groupKey = extractor.getGroupKey(); 093 String extractorId = extractor.getName(); 094 095 logger.debug("Applying " + extractorId + " mojo extractor"); 096 097 List<MojoDescriptor> extractorDescriptors = extractor.execute(request); 098 099 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}