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.util; 020 021import java.io.File; 022import java.net.MalformedURLException; 023import java.net.URL; 024import java.net.URLClassLoader; 025import java.util.ArrayList; 026import java.util.Collections; 027import java.util.Comparator; 028import java.util.HashMap; 029import java.util.List; 030import java.util.Map; 031 032import org.apache.maven.artifact.DependencyResolutionRequiredException; 033import org.apache.maven.plugin.descriptor.MojoDescriptor; 034import org.apache.maven.plugin.descriptor.Parameter; 035import org.apache.maven.project.MavenProject; 036import org.apache.maven.reporting.MavenReport; 037import org.codehaus.plexus.util.DirectoryScanner; 038import org.codehaus.plexus.util.FileUtils; 039import org.codehaus.plexus.util.StringUtils; 040 041/** 042 * Convenience methods to play with Maven plugins. 043 * 044 * @author jdcasey 045 * 046 */ 047public final class PluginUtils { 048 private PluginUtils() { 049 // nop 050 } 051 052 /** 053 * Expression associated with class types to recognize Maven objects (injected in fact as parameters by <a 054 * href="/ref/current/maven-core/apidocs/org/apache/maven/plugin/PluginParameterExpressionEvaluator.html"> 055 * maven-core's PluginParameterExpressionEvaluator</a>) like components ("real" components are injected by Plexus). 056 * 057 * @deprecated wrong approach (fake components), documented parameter default values instead to learn people how to 058 * discover them 059 */ 060 @Deprecated 061 public static final Map<String, String> MAVEN_COMPONENTS; 062 063 static { 064 Map<String, String> mavenComponents = new HashMap<>(); 065 066 mavenComponents.put("org.apache.maven.execution.MavenSession", "${session}"); 067 mavenComponents.put("org.apache.maven.project.MavenProject", "${project}"); 068 mavenComponents.put("org.apache.maven.plugin.MojoExecution", "${mojoExecution}"); 069 mavenComponents.put("org.apache.maven.plugin.descriptor.PluginDescriptor", "${plugin}"); 070 mavenComponents.put("org.apache.maven.settings.Settings", "${settings}"); 071 072 mavenComponents.put("org.apache.maven.api.Session", "${session}"); 073 mavenComponents.put("org.apache.maven.api.Project", "${project}"); 074 mavenComponents.put("org.apache.maven.api.MojoExecution", "${mojoExecution}"); 075 // TODO: apiv4: add PluginDescriptor to the api ? 076 // mavenComponents.put( "org.apache.maven.api.descriptor.PluginDescriptor", "${plugin}" ); 077 mavenComponents.put("org.apache.maven.api.settings.Settings", "${settings}"); 078 079 MAVEN_COMPONENTS = Collections.unmodifiableMap(mavenComponents); 080 } 081 082 /** 083 * @param basedir not null 084 * @param include not null 085 * @return list of included files with default SCM excluded files 086 */ 087 public static String[] findSources(String basedir, String include) { 088 return PluginUtils.findSources(basedir, include, null); 089 } 090 091 /** 092 * @param basedir not null 093 * @param include not null 094 * @param exclude could be null 095 * @return list of included files 096 */ 097 public static String[] findSources(String basedir, String include, String exclude) { 098 DirectoryScanner scanner = new DirectoryScanner(); 099 scanner.setBasedir(basedir); 100 scanner.setIncludes(new String[] {include}); 101 if (!(exclude == null || exclude.isEmpty())) { 102 scanner.setExcludes(new String[] {exclude, StringUtils.join(FileUtils.getDefaultExcludes(), ",")}); 103 } else { 104 scanner.setExcludes(FileUtils.getDefaultExcludes()); 105 } 106 107 scanner.scan(); 108 109 return scanner.getIncludedFiles(); 110 } 111 112 /** 113 * Sorts the specified mojo descriptors by goal name. 114 * 115 * @param mojoDescriptors The mojo descriptors to sort, may be <code>null</code>. 116 * @see MojoDescriptor#getGoal() 117 */ 118 public static void sortMojos(List<MojoDescriptor> mojoDescriptors) { 119 if (mojoDescriptors != null) { 120 Collections.sort(mojoDescriptors, new Comparator<MojoDescriptor>() { 121 /** {@inheritDoc} */ 122 @Override 123 public int compare(MojoDescriptor mojo0, MojoDescriptor mojo1) { 124 return mojo0.getGoal().compareToIgnoreCase(mojo1.getGoal()); 125 } 126 }); 127 } 128 } 129 130 /** 131 * Sorts the specified mojo parameters by name. 132 * 133 * @param parameters The mojo parameters to sort, may be <code>null</code>. 134 * @see Parameter#getName() 135 * @since 2.4.4 136 */ 137 public static void sortMojoParameters(List<Parameter> parameters) { 138 if (parameters != null) { 139 Collections.sort(parameters, new Comparator<Parameter>() { 140 /** {@inheritDoc} */ 141 @Override 142 public int compare(Parameter parameter1, Parameter parameter2) { 143 return parameter1.getName().compareToIgnoreCase(parameter2.getName()); 144 } 145 }); 146 } 147 } 148 149 /** 150 * @param mojoClassName a fully qualified Mojo implementation class name, not null 151 * @param project a MavenProject instance, could be null 152 * @return <code>true</code> if the Mojo class implements <code>MavenReport</code>, 153 * <code>false</code> otherwise. 154 * @throws IllegalArgumentException if any 155 * @since 3.10.0 156 */ 157 public static boolean isMavenReport(String mojoClassName, MavenProject project) throws IllegalArgumentException { 158 if (mojoClassName == null) { 159 throw new IllegalArgumentException("mojo implementation should be declared"); 160 } 161 162 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 163 if (project != null) { 164 List<String> classPathStrings; 165 try { 166 classPathStrings = project.getCompileClasspathElements(); 167 if (project.getExecutionProject() != null) { 168 classPathStrings.addAll(project.getExecutionProject().getCompileClasspathElements()); 169 } 170 } catch (DependencyResolutionRequiredException e) { 171 throw new IllegalArgumentException(e); 172 } 173 174 List<URL> urls = new ArrayList<>(classPathStrings.size()); 175 for (String classPathString : classPathStrings) { 176 try { 177 urls.add(new File(classPathString).toURL()); 178 } catch (MalformedURLException e) { 179 throw new IllegalArgumentException(e); 180 } 181 } 182 183 classLoader = new URLClassLoader(urls.toArray(new URL[urls.size()]), classLoader); 184 } 185 186 try { 187 Class<?> clazz = Class.forName(mojoClassName, false, classLoader); 188 189 return MavenReport.class.isAssignableFrom(clazz); 190 } catch (ClassNotFoundException e) { 191 return false; 192 } 193 } 194}