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.List;
029
030import org.apache.maven.artifact.DependencyResolutionRequiredException;
031import org.apache.maven.plugin.descriptor.MojoDescriptor;
032import org.apache.maven.plugin.descriptor.Parameter;
033import org.apache.maven.project.MavenProject;
034import org.apache.maven.reporting.MavenReport;
035import org.codehaus.plexus.util.DirectoryScanner;
036import org.codehaus.plexus.util.FileUtils;
037import org.codehaus.plexus.util.StringUtils;
038
039/**
040 * Convenience methods to play with Maven plugins.
041 *
042 * @author jdcasey
043 *
044 */
045public final class PluginUtils {
046    private PluginUtils() {
047        // nop
048    }
049
050    /**
051     * @param basedir not null
052     * @param include not null
053     * @return list of included files with default SCM excluded files
054     */
055    public static String[] findSources(String basedir, String include) {
056        return PluginUtils.findSources(basedir, include, null);
057    }
058
059    /**
060     * @param basedir not null
061     * @param include not null
062     * @param exclude could be null
063     * @return list of included files
064     */
065    public static String[] findSources(String basedir, String include, String exclude) {
066        DirectoryScanner scanner = new DirectoryScanner();
067        scanner.setBasedir(basedir);
068        scanner.setIncludes(new String[] {include});
069        if (!(exclude == null || exclude.isEmpty())) {
070            scanner.setExcludes(new String[] {exclude, StringUtils.join(FileUtils.getDefaultExcludes(), ",")});
071        } else {
072            scanner.setExcludes(FileUtils.getDefaultExcludes());
073        }
074
075        scanner.scan();
076
077        return scanner.getIncludedFiles();
078    }
079
080    /**
081     * Sorts the specified mojo descriptors by goal name.
082     *
083     * @param mojoDescriptors The mojo descriptors to sort, may be <code>null</code>.
084     * @see MojoDescriptor#getGoal()
085     */
086    public static void sortMojos(List<MojoDescriptor> mojoDescriptors) {
087        if (mojoDescriptors != null) {
088            Collections.sort(mojoDescriptors, new Comparator<MojoDescriptor>() {
089                /** {@inheritDoc} */
090                @Override
091                public int compare(MojoDescriptor mojo0, MojoDescriptor mojo1) {
092                    return mojo0.getGoal().compareToIgnoreCase(mojo1.getGoal());
093                }
094            });
095        }
096    }
097
098    /**
099     * Sorts the specified mojo parameters by name.
100     *
101     * @param parameters The mojo parameters to sort, may be <code>null</code>.
102     * @see Parameter#getName()
103     * @since 2.4.4
104     */
105    public static void sortMojoParameters(List<Parameter> parameters) {
106        if (parameters != null) {
107            Collections.sort(parameters, new Comparator<Parameter>() {
108                /** {@inheritDoc} */
109                @Override
110                public int compare(Parameter parameter1, Parameter parameter2) {
111                    return parameter1.getName().compareToIgnoreCase(parameter2.getName());
112                }
113            });
114        }
115    }
116
117    /**
118     * @param mojoClassName a fully qualified Mojo implementation class name, not null
119     * @param project a MavenProject instance, could be null
120     * @return <code>true</code> if the Mojo class implements <code>MavenReport</code>,
121     * <code>false</code> otherwise.
122     * @throws IllegalArgumentException if any
123     * @since 3.10.0
124     */
125    public static boolean isMavenReport(String mojoClassName, MavenProject project) throws IllegalArgumentException {
126        if (mojoClassName == null) {
127            throw new IllegalArgumentException("mojo implementation should be declared");
128        }
129
130        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
131        if (project != null) {
132            List<String> classPathStrings;
133            try {
134                classPathStrings = project.getCompileClasspathElements();
135                if (project.getExecutionProject() != null) {
136                    classPathStrings.addAll(project.getExecutionProject().getCompileClasspathElements());
137                }
138            } catch (DependencyResolutionRequiredException e) {
139                throw new IllegalArgumentException(e);
140            }
141
142            List<URL> urls = new ArrayList<>(classPathStrings.size());
143            for (String classPathString : classPathStrings) {
144                try {
145                    urls.add(new File(classPathString).toURL());
146                } catch (MalformedURLException e) {
147                    throw new IllegalArgumentException(e);
148                }
149            }
150
151            classLoader = new URLClassLoader(urls.toArray(new URL[urls.size()]), classLoader);
152        }
153
154        try {
155            Class<?> clazz = Class.forName(mojoClassName, false, classLoader);
156
157            return MavenReport.class.isAssignableFrom(clazz);
158        } catch (ClassNotFoundException e) {
159            return false;
160        }
161    }
162}