All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.technophobia.substeps.glossary.CustomDoclet Maven / Gradle / Ivy

/*
 *  Copyright Technophobia Ltd 2012
 *
 *   This file is part of Substeps.
 *
 *    Substeps is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU Lesser General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    Substeps is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public License
 *    along with Substeps.  If not, see .
 */
package com.technophobia.substeps.glossary;

import com.sun.javadoc.*;
import com.technophobia.substeps.model.SubSteps.Step;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * TODO
 *
 * @author imoore
 */
public class CustomDoclet extends Doclet {

    private static final Logger log = LoggerFactory.getLogger(CustomDoclet.class);
    private static List classStepTagsList;


    public static void setExpressionList(final List expressionList) {
        classStepTagsList = expressionList;
    }


    public static List getExpressions() {
        return classStepTagsList;
    }


    public static boolean start(final RootDoc root) {

        final ClassDoc[] classes = root.classes();

        for (final ClassDoc cd : classes) {

            final StepImplementationsDescriptor classStepTags = new StepImplementationsDescriptor(
                    cd.qualifiedName());

            classStepTagsList.add(classStepTags);

            Class implClass = null;
            Method[] implMethods = null;
            try {

                implClass = root.getClass().getClassLoader().loadClass(cd.qualifiedTypeName());
                implMethods = implClass.getMethods();

                final MethodDoc[] methods = cd.methods();

                for (final MethodDoc md : methods) {

                    final Method underlyingMethod = getMethod(implMethods, md);

                    if (underlyingMethod != null) {
                        final Step annotation = underlyingMethod.getAnnotation(Step.class);

                        if (annotation != null)

                        {
                            final StepDescriptor expression = new StepDescriptor();

                            classStepTags.addStepTags(expression);

                            expression.setDescription(md.commentText().replaceAll("\n", " "));

                            expression.setExample(getSingleJavadocTagValue(md, "example"));
                            expression.setSection(getSingleJavadocTagValue(md, "section"));

                            String line = annotation.value();

                            final Parameter[] parameters = md.parameters();
                            if (parameters != null && parameters.length > 0) {
                                for (final Parameter p : parameters) {
                                    // replace any captures with 

                                    line = line.replaceFirst("\\([^\\)]*\\)", "<" + p.name() + ">");

                                    p.typeName();
                                }
                            }
                            line = line.replaceAll("\\?", "");
                            line = line.replaceAll("\\\\", "");
                            expression.setExpression(line);
                        }
                    }
                }
            } catch (final ClassNotFoundException e) {
                log.error("ClassNotFoundException", e);
            }

        }

        return true;
    }


    /**
     * @param md
     * @param tagName
     */
    private static String getSingleJavadocTagValue(final MethodDoc md, final String tagName) {
        String rtn = null;
        final Tag[] tags = md.tags(tagName);
        if (tags != null && tags.length > 0) {
            rtn = tags[0].text().replace("@" + tagName, "");
            rtn.replaceAll("\n", " ");
        }

        return rtn != null ? rtn : "";
    }


    /**
     * @param implMethods
     * @param md
     * @return
     */
    private static Method getMethod(final Method[] implMethods, final MethodDoc md) {
        Method rtn = null;

        int desiredNumberOfParams = 0;

        final Parameter[] parameters = md.parameters();
        if (parameters != null) {
            desiredNumberOfParams = parameters.length;
        }

        final List candidateMethods = new ArrayList();

        // try and match by name
        for (final Method m : implMethods) {
            if (m.getName().equals(md.name())) {
                if (m.getParameterTypes().length == desiredNumberOfParams) {
                    candidateMethods.add(m);
                }
            }
        }

        if (candidateMethods.size() > 1) {
            throw new IllegalStateException("need to impl parameter type matching");
        }

        if (!candidateMethods.isEmpty()) {
            rtn = candidateMethods.get(0);
        }

        return rtn;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy