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