Package au.net.ocean.maven.plugin.extractor

Source Code of au.net.ocean.maven.plugin.extractor.JavaAnnotationMojoDescriptorExtractor

/*******************************************************************************
*
* Copyright (c) 2007, Dave Whitla
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*  * Redistributions of source code must retain the above copyright notice,
*    this list of conditions and the following disclaimer.
*
*  * Redistributions in binary form must reproduce the above copyright notice,
*    this list of conditions and the following disclaimer in the documentation
*    and/or other materials provided with the distribution.
*
*  * Neither the name of the copyright holder nor the names of contributors
*    may be used to endorse or promote products derived from this software
*    without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/

package au.net.ocean.maven.plugin.extractor;

import au.net.ocean.maven.plugin.annotation.Component;
import au.net.ocean.maven.plugin.annotation.Execution;
import au.net.ocean.maven.plugin.annotation.Mojo;
import au.net.ocean.maven.plugin.annotation.Parameter;
import au.net.ocean.maven.plugin.annotation.Phase;
import au.net.ocean.maven.plugin.annotation.ReadOnly;
import au.net.ocean.maven.plugin.annotation.Required;
import au.net.ocean.maven.plugin.extractor.util.ProjectCompileClassPathLoader;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.plugin.descriptor.DuplicateParameterException;
import org.apache.maven.plugin.descriptor.InvalidParameterException;
import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.descriptor.Requirement;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.logging.AbstractLogEnabled;

import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
* Generate a plugin descriptor by parsing runtime-retained annotations.
* <p/>
*
* @author <a href="mailto:dave.whitla@ocean.net.au">Dave Whitla</a>
* @version $Id: JavaAnnotationMojoDescriptorExtractor.java 0 26/03/2008 15:43:57 dwhitla $
*/
public class JavaAnnotationMojoDescriptorExtractor extends AbstractLogEnabled implements org.apache.maven.tools.plugin.extractor.MojoDescriptorExtractor {

    private static final String JAVA_SOURCE_SUFFIX = ".java";
    private static final List<String> DIRECTORY_EXCLUDE_PATTERNS = Arrays.asList("CVS",".svn");
    private static final String PACKAGE_SEPARATOR = ".";
   

    // TODO: remove when backward compatibility is no longer an issue.
    private void validateParameters(MojoDescriptor mojoDescriptor) throws InvalidParameterException {
        int parameterIndex = 0;
        for (org.apache.maven.plugin.descriptor.Parameter parameter :
                (List<org.apache.maven.plugin.descriptor.Parameter>)mojoDescriptor.getParameters()) {
            parameterIndex++;
            if (parameter.getName() == null) {
                throw new InvalidParameterException("name", parameterIndex);
            }
            if (parameter.getType() == null) {
                throw new InvalidParameterException("type", parameterIndex);
            }
            if (parameter.getDescription() == null) {
                throw new InvalidParameterException("description", parameterIndex);
            }
        }
    }

    /**
     * @inheritDoc
     */
    public List execute(MavenProject project, PluginDescriptor pluginDescriptor) throws InvalidPluginDescriptorException {
        final List<MojoDescriptor> descriptors = new ArrayList<MojoDescriptor>();
        try {
            ProjectCompileClassPathLoader compileClassPathLoader = new ProjectCompileClassPathLoader(project, getClass().getClassLoader());
            ClassLoader savedContextClassLoader = Thread.currentThread().getContextClassLoader();
            Thread.currentThread().setContextClassLoader(compileClassPathLoader);

            for (Object compileSourceRoot : project.getCompileSourceRoots()) {
                getLogger().debug("processing source root: " + compileSourceRoot);
                descriptors.addAll(extractMojosFromPath(new File(compileSourceRoot.toString()), "", pluginDescriptor));
            }

            Thread.currentThread().setContextClassLoader(savedContextClassLoader);
        } catch (DependencyResolutionRequiredException e) {
            getLogger().error(e.getMessage(), e);
        }
        return descriptors;
    }

    private Set<MojoDescriptor> extractMojosFromPath(File packageRoot, String packagePrefix, PluginDescriptor pluginDescriptor)
            throws InvalidPluginDescriptorException {
        Set<MojoDescriptor> mojos = new HashSet<MojoDescriptor>();
        for (File file : packageRoot.listFiles()) {
            String fileName = file.getName();
            if (file.isDirectory() && !DIRECTORY_EXCLUDE_PATTERNS.contains(fileName)) {
                getLogger().debug("processing source package: " + packagePrefix + fileName);
                String subpackagePrefix = packagePrefix + fileName + PACKAGE_SEPARATOR;
                mojos.addAll(extractMojosFromPath(file, subpackagePrefix, pluginDescriptor));
            } else if (fileName.endsWith(JAVA_SOURCE_SUFFIX)) {
                getLogger().debug("processing source file: " + packagePrefix + fileName);
                try {
                    String className = packagePrefix + fileName.substring(0, fileName.lastIndexOf(JAVA_SOURCE_SUFFIX));
                    Class<?> clazz = Class.forName(className, false, Thread.currentThread().getContextClassLoader());
                    MojoDescriptor mojo = extractMojo(clazz);
                    if (mojo != null) {
                        mojo.setPluginDescriptor(pluginDescriptor);
                        mojos.add(mojo);
                    }
                } catch (ClassNotFoundException e) {
                    getLogger().info(e.toString());
                }
            }
        }
        return mojos;
    }

    private MojoDescriptor extractMojo(Class<?> clazz) throws InvalidPluginDescriptorException {
        getLogger().debug("scanning class: " + clazz.getName());
        MojoDescriptor mojoDescriptor = null;
        Mojo mojo = clazz.getAnnotation(Mojo.class);
        if (mojo != null) {
            getLogger().info("found @Mojo in: " + clazz.getName());
            mojoDescriptor = new MojoDescriptor();
            mojoDescriptor.setLanguage("java");
            mojoDescriptor.setImplementation(clazz.getName());
            mojoDescriptor.setDescription(mojo.description().trim());
            mojoDescriptor.setInstantiationStrategy(mojo.instantiationStrategy().value);
            mojoDescriptor.setExecutionStrategy(mojo.executionStrategy().value);
            String configurator = clazz.getAnnotation(Mojo.class).configurator();
            if (configurator.trim().length() > 0) {
                mojoDescriptor.setComponentConfigurator(configurator.trim());
            }
            mojoDescriptor.setGoal(clazz.getAnnotation(Mojo.class).goal().trim());
            mojoDescriptor.setPhase(mojo.phase().value);
            Execution execute = mojo.execute();
            String lifecycle = execute.lifecycle().trim().length() == 0 ? null : execute.lifecycle().trim();
            String goal = execute.goal().trim().length() == 0 ? null : execute.goal().trim();
            Phase phase = execute.phase();
            if (goal != null || phase != Phase.None) {
                if (goal != null) {
                    if (lifecycle != null) {
                        throw new InvalidPluginDescriptorException("'goal' cannot be specified with 'lifecycle' in execute annotation");
                    }
                    if (phase != Phase.None) {
                        throw new InvalidPluginDescriptorException("execute annotation cannot specify both 'phase' and 'goal'");
                    }
                    mojoDescriptor.setExecuteGoal(goal);
                } else {
                    mojoDescriptor.setExecutePhase(phase.value);
                    if (lifecycle != null) {
                        mojoDescriptor.setExecuteLifecycle(lifecycle);
                    }
                }
            }
            mojoDescriptor.setDependencyResolutionRequired(mojo.requiresDependencyResolution().value);
            mojoDescriptor.setProjectRequired(mojo.requiresProject());
            mojoDescriptor.setAggregator(mojo.aggregator());
            mojoDescriptor.setDirectInvocationOnly(mojo.requiresDirectInvocation());
            mojoDescriptor.setOnlineRequired(mojo.requiresOnline());
            mojoDescriptor.setInheritedByDefault(mojo.inheritByDefault());
            if (mojo.deprecated().trim().length() > 0) {
                mojoDescriptor.setDeprecated(mojo.deprecated());
            }
            // extract parameters working back through the inheritancce hierarchy
            while (!clazz.equals(Object.class)) {
                for (Field field : clazz.getDeclaredFields()) {
                    org.apache.maven.plugin.descriptor.Parameter parameter = extractParameter(field);
                    if (parameter != null) {
                        mojoDescriptor.addParameter(parameter);
                        if ("${reports}".equals(parameter.getExpression())) {
                            mojoDescriptor.setRequiresReports(true);
                        }
                    }
                }
                clazz = clazz.getSuperclass();
            }
            validateParameters(mojoDescriptor);
        }
        return mojoDescriptor;
    }

    private org.apache.maven.plugin.descriptor.Parameter extractParameter(Field field) throws DuplicateParameterException {
        getLogger().debug("scanning field: " + field.getName());
        org.apache.maven.plugin.descriptor.Parameter parameterDescriptor = null;
        Parameter parameter = field.getAnnotation(Parameter.class);
        Component component = field.getAnnotation(Component.class);
        if (parameter != null || component != null) {
            Class<?> type = field.getType();
            StringBuffer typeNameBuffer = new StringBuffer();
            while (type.isArray()) {
                typeNameBuffer.append("[]");
                type = type.getComponentType();
            }
            String typeName = typeNameBuffer.insert(0, type.getName()).toString();
            parameterDescriptor = new org.apache.maven.plugin.descriptor.Parameter();
            parameterDescriptor.setType(typeName);
            // component overrides parameter if both are present
            if (component != null) {
                getLogger().info("found @Component: (" + typeName + "):" + field.getName());
                parameterDescriptor.setDescription(component.description());
                String role = component.role().trim();
                if (role.length() == 0) {
                    role = typeName;
                }
                String roleHint = component.roleHint().trim();
                if (roleHint.length() == 0) {
                    roleHint = null;
                }
                parameterDescriptor.setRequirement(new Requirement(role, roleHint));
                parameterDescriptor.setName(field.getName());
            } else {
                getLogger().info("found @Parameter: (" + typeName + "):" + field.getName());
                parameterDescriptor.setDescription(parameter.description());
                String property = parameter.property().trim();
                parameterDescriptor.setName(property.length() > 0 ? property : field.getName());
                parameterDescriptor.setRequired(field.isAnnotationPresent(Required.class));
                parameterDescriptor.setEditable(!field.isAnnotationPresent(ReadOnly.class));
//                    DocletTag deprecationTag = field.getTagByName(DEPRECATED);
//                    if (deprecationTag != null) {
//                        parameterDescriptor.setDeprecated(deprecationTag.getValue());
//                    }
                String alias = parameter.alias().trim();
                if (alias.length() > 0) {
                    parameterDescriptor.setAlias(alias);
                }
                parameterDescriptor.setExpression(parameter.expression().trim());
                parameterDescriptor.setDefaultValue(parameter.defaultValue());
            }
        }
        return parameterDescriptor;
    }

}
TOP

Related Classes of au.net.ocean.maven.plugin.extractor.JavaAnnotationMojoDescriptorExtractor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.