org.mule.devkit.validation.JavaDocValidator.java Source code

Java tutorial

Introduction

Here is the source code for org.mule.devkit.validation.JavaDocValidator.java

Source

/**
 * Mule Development Kit
 * Copyright 2010-2011 (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.mule.devkit.validation;

import org.apache.commons.lang.StringUtils;
import org.mule.api.annotations.Configurable;
import org.mule.api.annotations.Connect;
import org.mule.api.annotations.Disconnect;
import org.mule.api.annotations.Processor;
import org.mule.api.annotations.Source;
import org.mule.api.annotations.Transformer;
import org.mule.devkit.GeneratorContext;
import org.mule.devkit.generation.DevKitTypeElement;
import org.mule.util.IOUtils;

import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class JavaDocValidator implements Validator {

    @Override
    public boolean shouldValidate(DevKitTypeElement typeElement, GeneratorContext context) {
        return typeElement.isModuleOrConnector() && !context.isEnvOptionSet("skipJavaDocValidation");
    }

    @Override
    public void validate(DevKitTypeElement typeElement, GeneratorContext context) throws ValidationException {

        if (!hasComment(typeElement.getInnerTypeElement(), context)) {
            throw new ValidationException(typeElement, "Class " + typeElement.getQualifiedName().toString()
                    + " is not properly documented. A summary is missing.");
        }

        if (!context.getJavaDocUtils().hasTag("author", typeElement.getInnerTypeElement())) {
            throw new ValidationException(typeElement,
                    "Class " + typeElement.getQualifiedName().toString() + " needs to have an @author tag.");
        }

        for (VariableElement variable : typeElement.getFieldsAnnotatedWith(Configurable.class)) {
            if (!hasComment(variable, context)) {
                throw new ValidationException(variable, "Field " + variable.getSimpleName().toString()
                        + " is not properly documented. The description is missing.");
            }
        }

        for (ExecutableElement method : typeElement.getMethodsAnnotatedWith(Processor.class)) {
            validateMethod(typeElement, context, method);
        }

        for (ExecutableElement method : typeElement.getMethodsAnnotatedWith(Source.class)) {
            validateMethod(typeElement, context, method);
        }

        for (ExecutableElement method : typeElement.getMethodsAnnotatedWith(Transformer.class)) {
            validateMethod(typeElement, context, method);
        }

        for (ExecutableElement method : typeElement.getMethodsAnnotatedWith(Connect.class)) {
            validateAllParameters(context, method);
        }

        for (ExecutableElement method : typeElement.getMethodsAnnotatedWith(Disconnect.class)) {
            validateAllParameters(context, method);
        }
    }

    private void validateAllParameters(GeneratorContext context, ExecutableElement method)
            throws ValidationException {
        for (VariableElement variable : method.getParameters()) {
            if (!hasParameterComment(variable.getSimpleName().toString(), variable.getEnclosingElement(),
                    context)) {
                throw new ValidationException(variable, "Parameter " + variable.getSimpleName().toString()
                        + " of method " + method.getSimpleName().toString()
                        + " is not properly documented. A matching @param in the method documentation was not found. ");
            }
        }
    }

    private void validateMethod(DevKitTypeElement typeElement, GeneratorContext context, ExecutableElement method)
            throws ValidationException {
        if (!hasComment(method, context)) {
            throw new ValidationException(method, "Method " + method.getSimpleName().toString()
                    + " is not properly documented. A description of what it can do is missing.");
        }

        if (!method.getReturnType().toString().equals("void")
                && !method.getReturnType().toString().contains("StopSourceCallback")) {
            if (!context.getJavaDocUtils().hasTag("return", method)) {
                throw new ValidationException(typeElement,
                        "The return type of a non-void method must be documented. Method "
                                + method.getSimpleName().toString() + " is at fault. Missing @return.");
            }
        }

        if (exampleDoesNotExist(context, method)) {
            throw new ValidationException(typeElement, "Method " + method.getSimpleName().toString()
                    + " does not have the example pointed by the {@sample.xml} tag");
        }

        validateAllParameters(context, method);
    }

    private boolean hasComment(Element element, GeneratorContext context) {
        String comment = context.getJavaDocUtils().getSummary(element);
        return StringUtils.isNotBlank(comment);

    }

    private boolean hasParameterComment(String paramName, Element element, GeneratorContext context) {
        String comment = context.getJavaDocUtils().getParameterSummary(paramName, element);
        return StringUtils.isNotBlank(comment);
    }

    protected boolean exampleDoesNotExist(GeneratorContext context, ExecutableElement method)
            throws ValidationException {

        if (!context.getJavaDocUtils().hasTag("sample.xml", method)) {
            throw new ValidationException(method, "Method " + method.getSimpleName().toString()
                    + " does not contain an example using {@sample.xml} tag.");
        }

        boolean found = false;
        String sample = context.getJavaDocUtils().getTagContent("sample.xml", method);
        String[] split = sample.split(" ");

        if (split.length != 2) {
            throw new ValidationException(method,
                    "Check @sample.xml javadoc tag because is not well formed for method: "
                            + method.getSimpleName());
        }

        String pathToExamplesFile = split[0];
        String exampleName = split[1];

        TypeElement typeElement = (TypeElement) method.getEnclosingElement();
        String sourcePath = context.getSourceUtils().getPath(typeElement);
        int packageCount = StringUtils.countMatches(typeElement.getQualifiedName().toString(), ".") + 1;
        while (packageCount > 0) {
            sourcePath = sourcePath.substring(0, sourcePath.lastIndexOf("/"));
            packageCount--;
        }

        try {
            File docFile = new File(sourcePath, pathToExamplesFile);
            String examplesFileContent = IOUtils.toString(new FileInputStream(docFile));
            if (examplesFileContent.contains("BEGIN_INCLUDE(" + exampleName + ")")) {
                found = true;
            }
        } catch (IOException e) {
            // do nothing
        }

        return !found;
    }
}