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; 042import org.codehaus.plexus.util.StringUtils; 043 044/** 045 * @author jdcasey 046 */ 047@Named 048public class DefaultMojoScanner extends AbstractLogEnabled implements MojoScanner { 049 050 private Map<String, MojoDescriptorExtractor> mojoDescriptorExtractors; 051 052 /** 053 * The names of the active extractors 054 */ 055 private Set<String> activeExtractors; 056 057 /** 058 * Default constructor 059 * 060 * @param extractors not null 061 */ 062 @Inject 063 public DefaultMojoScanner(Map<String, MojoDescriptorExtractor> extractors) { 064 this.mojoDescriptorExtractors = extractors; 065 066 this.enableLogging(new ConsoleLogger(Logger.LEVEL_INFO, "standalone-scanner-logger")); 067 } 068 069 /** 070 * Empty constructor 071 */ 072 public DefaultMojoScanner() { 073 // nop 074 } 075 076 /** 077 * {@inheritDoc} 078 */ 079 @Override 080 public void populatePluginDescriptor(PluginToolsRequest request) 081 throws ExtractionException, InvalidPluginDescriptorException { 082 Logger logger = getLogger(); 083 084 int numMojoDescriptors = 0; 085 086 List<MojoDescriptorExtractor> orderedExtractors = getOrderedExtractors(); 087 088 logger.debug("Using " + orderedExtractors.size() + " mojo extractors."); 089 090 HashMap<String, Integer> groupStats = new HashMap<>(); 091 092 for (MojoDescriptorExtractor extractor : orderedExtractors) { 093 GroupKey groupKey = extractor.getGroupKey(); 094 String extractorId = extractor.getName(); 095 096 logger.debug("Applying " + extractorId + " mojo extractor"); 097 098 List<MojoDescriptor> extractorDescriptors = extractor.execute(request); 099 100 int extractorDescriptorsCount = extractorDescriptors.size(); 101 102 logger.info(extractorId + " mojo extractor found " + extractorDescriptorsCount + " mojo descriptor" 103 + (extractorDescriptorsCount > 1 ? "s" : "") + "."); 104 numMojoDescriptors += extractorDescriptorsCount; 105 106 if (extractor.isDeprecated() && extractorDescriptorsCount > 0) { 107 logger.warn(""); 108 logger.warn("Deprecated extractor " + extractorId 109 + " extracted " + extractorDescriptorsCount 110 + " descriptor" + (extractorDescriptorsCount > 1 ? "s" : "") 111 + ". Upgrade your Mojo definitions."); 112 if (GroupKey.JAVA_GROUP.equals(groupKey.getGroup())) { 113 logger.warn("You should use Mojo Annotations instead of Javadoc tags."); 114 } 115 logger.warn(""); 116 } 117 118 if (groupStats.containsKey(groupKey.getGroup())) { 119 groupStats.put(groupKey.getGroup(), groupStats.get(groupKey.getGroup()) + extractorDescriptorsCount); 120 } else { 121 groupStats.put(groupKey.getGroup(), extractorDescriptorsCount); 122 } 123 124 for (MojoDescriptor descriptor : extractorDescriptors) { 125 logger.debug("Adding mojo: " + descriptor + " to plugin descriptor."); 126 127 descriptor.setPluginDescriptor(request.getPluginDescriptor()); 128 129 request.getPluginDescriptor().addMojo(descriptor); 130 } 131 } 132 133 logger.debug("Discovered descriptors by groups: " + groupStats); 134 135 if (numMojoDescriptors == 0 && !request.isSkipErrorNoDescriptorsFound()) { 136 throw new InvalidPluginDescriptorException("No mojo definitions were found for plugin: " 137 + request.getPluginDescriptor().getPluginLookupKey() + "."); 138 } 139 } 140 141 /** 142 * Returns a list of extractors sorted by {@link MojoDescriptorExtractor#getGroupKey()}s, never {@code null}. 143 */ 144 private List<MojoDescriptorExtractor> getOrderedExtractors() throws ExtractionException { 145 Set<String> extractors = activeExtractors; 146 147 if (extractors == null) { 148 extractors = new HashSet<>(mojoDescriptorExtractors.keySet()); 149 } 150 151 ArrayList<MojoDescriptorExtractor> orderedExtractors = new ArrayList<>(); 152 for (String extractorId : extractors) { 153 MojoDescriptorExtractor extractor = mojoDescriptorExtractors.get(extractorId); 154 155 if (extractor == null) { 156 throw new ExtractionException("No mojo extractor with '" + extractorId + "' id."); 157 } 158 159 orderedExtractors.add(extractor); 160 } 161 162 Collections.sort(orderedExtractors, MojoDescriptorExtractorComparator.INSTANCE); 163 164 return orderedExtractors; 165 } 166 167 @Override 168 public void setActiveExtractors(Set<String> extractors) { 169 if (extractors == null) { 170 this.activeExtractors = null; 171 } else { 172 this.activeExtractors = new HashSet<>(); 173 174 for (String extractor : extractors) { 175 if (StringUtils.isNotEmpty(extractor)) { 176 this.activeExtractors.add(extractor); 177 } 178 } 179 } 180 } 181}