com.iggroup.oss.restdoclet.doclet.util.DocletUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.iggroup.oss.restdoclet.doclet.util.DocletUtils.java

Source

/*
 * #%L restdoc-doclet %% Copyright (C) 2012 IG Group %% 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. #L%
 */
package com.iggroup.oss.restdoclet.doclet.util;

import static com.iggroup.oss.restdoclet.doclet.util.AnnotationUtils.isAnnotated;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Properties;

import org.apache.log4j.PropertyConfigurator;

import com.iggroup.oss.restdoclet.doclet.type.Controller;
import com.iggroup.oss.restdoclet.doclet.type.FieldParameter;
import com.iggroup.oss.restdoclet.doclet.type.builder.FieldParameterBuilder;
import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.FieldDoc;
import com.sun.javadoc.MethodDoc;

/**
 * Manages properties of <code>doclet</code> module. This class also contains
 * utility operations.
 */
public final class DocletUtils {

    /**
     * The name of the file that contains the properties. This file is packaged
     * with <code>doclet</code>'s archive.
     */
    public static final String PROPERTIES_FILE = "oss-restdoclet-doclet.properties";

    private static final String GETTER_PREFIX = "get";

    /**
     * Environment variable to control restdoc logging
     */
    private static final String RESTDOCLET_LOGGING = "RESTDOCLET_LOGGING";

    /**
     * The property containing the artifact-identifier of <code>doclet</code>
     * module.
     */
    public static final String ARTIFACT_ID = "project.artifactId";

    /**
     * The singleton instance of this class.
     */
    private static DocletUtils instance;

    /**
     * The properties of <code>doclet</code> module.
     */
    private final Properties properties;

    /**
     * Constructs the singleton instance of this class.
     * 
     * @throws IOException if <code>doclet</code>'s properties can't be read.
     */
    private DocletUtils() throws IOException {
        super();
        properties = new Properties();
        properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream(PROPERTIES_FILE));
    }

    /**
     * Gets the singleton instance of this class.
     * 
     * @return the singleton instance of this class.
     * @throws IOException if <code>doclet</code>'s properties can't be read.
     */
    public static DocletUtils getInstance() throws IOException {
        synchronized (PROPERTIES_FILE) {
            if (instance == null) {
                instance = new DocletUtils();
            }
            return instance;
        }
    }

    /**
     * Gets the properties of <code>doclet</code> module.
     * 
     * @return <code>doclet</code>'s properties.
     */
    public Properties getProperties() {
        return properties;
    }

    /**
     * Sets the properties of <code>doclet</code> module. This operation is not
     * supported.
     * 
     * @param properties <code>doclet</code>'s properties.
     */
    public void setProperties(final Properties properties) {
        throw new UnsupportedOperationException("DocletUtils.setProperties(Properties)");
    }

    /**
     * Gets the artifact-identifier of <code>doclet</code> module.
     * 
     * @return the artifact-identifier.
     * @throws IOException if <code>doclet</code>'s properties can't be read.
     */
    public static String artifactIdentifier() throws IOException {
        return getInstance().properties.getProperty(ARTIFACT_ID);
    }

    /**
     * Determines if a class is Spring's controller.
     * 
     * @param classDoc the Java documentation object of the class.
     * @return <code>true</code> if the class is a Spring's controller,
     *         <code>false</code> otherwise.
     */
    public static boolean isController(final ClassDoc classDoc) {
        return isAnnotated(classDoc, org.springframework.stereotype.Controller.class);
    }

    /**
     * Gets the file containing the documentation of a class.
     * 
     * @param classDoc the Java documentation object of the class.
     * @return the file containing documentation.
     */
    public static File documentationFile(final ClassDoc classDoc) {
        final StringBuffer path = new StringBuffer();
        path.append(classDoc.qualifiedName().replace('.', File.separatorChar));
        if (isController(classDoc)) {
            path.append(Controller.FILE_SUFFIX);
        } else {
            path.append(".class.xml");
        }
        final File doc = new File(path.toString());
        doc.getParentFile().mkdirs();
        return doc;
    }

    /**
     * Return a list of all fields that have a public getter
     * 
     * @param classDoc class documentation
     * @return list of all fields that have a public getter
     */
    public static Collection<FieldParameter> getPublicFields(final ClassDoc classDoc) {

        ArrayList<FieldParameter> fields = new ArrayList<FieldParameter>();

        MethodDoc[] methods = classDoc.methods();

        for (FieldDoc fieldDoc : classDoc.fields(false)) {

            boolean found = false;
            for (MethodDoc md : methods) {
                if (md.name().equalsIgnoreCase(GETTER_PREFIX + fieldDoc.name())) {
                    found = true;
                }
            }

            if (found) {
                fields.add(new FieldParameterBuilder().build(new FieldParameter(), fieldDoc));
            }
        }

        return fields;
    }

    /**
     * Initialise log4j based on RESTDOC_DEBUG environment variable
     */
    public static void initialiseLogging() {

        String debugLevel = System.getProperty(RESTDOCLET_LOGGING);

        if (debugLevel != null && (debugLevel.equalsIgnoreCase("debug") || debugLevel.equalsIgnoreCase("info")
                || debugLevel.equalsIgnoreCase("error"))) {

            System.out.println("Setting RESTDoclet logging level to : " + debugLevel);

            try {

                Properties logProperties = new Properties();

                InputStream is = DocletUtils.class.getClassLoader()
                        .getResourceAsStream("log4j.properties." + debugLevel.toLowerCase());

                if (is == null) {
                    System.err
                            .println("[ERROR] Failed to load file : log4j.properties." + debugLevel.toLowerCase());
                } else {
                    logProperties.load(is);
                    PropertyConfigurator.configure(logProperties);
                }

            } catch (Exception ioe) {
                System.err.println("[ERROR] - Failed to initialised RESTDoclet doclet logging");
                ioe.printStackTrace();
            }

        }
    }

    /**
     * Preserve the formatting of the javadoc string
     * 
     * @param javadoc
     * @return javadoc string wrapped with span element of type javadoc
     */
    public static String preserveJavadocFormatting(final String javadoc) {

        if (javadoc.contains("<span class=\"javadoc\">")) {

            return javadoc;

        }

        return "<span class=\"javadoc\">" + javadoc + "</span>";

    }

    public static MethodDoc findMethodDocumentation(final MethodDoc methodDoc) {

        // Look in parent class for javadoc
        if (methodDoc.commentText().contains("@inheritDoc")) {

            ClassDoc containingClass = methodDoc.containingClass();
            ClassDoc superClass = containingClass.superclass().asClassDoc();
            for (MethodDoc md : superClass.methods()) {
                if (md.name().equalsIgnoreCase(methodDoc.name())
                        && md.signature().equalsIgnoreCase(methodDoc.signature())) {

                    return md;
                }
            }

            // Look in interfaces for javadoc
            for (ClassDoc cd : containingClass.interfaces()) {
                for (MethodDoc md : cd.methods()) {
                    if (md.name().equalsIgnoreCase(methodDoc.name())
                            && md.signature().equalsIgnoreCase(methodDoc.signature())) {

                        return md;
                    }
                }
            }
        }
        return methodDoc;
    }
}