org.tldgen.TldDoclet.java Source code

Java tutorial

Introduction

Here is the source code for org.tldgen.TldDoclet.java

Source

package org.tldgen;

import static org.tldgen.util.JavadocUtils.getEnumAttribute;
import static org.tldgen.util.JavadocUtils.getStringAttribute;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.util.Set;
import java.util.TreeSet;

import org.apache.commons.io.FileUtils;
import org.tldgen.util.ArrayUtilities;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.tldgen.annotations.License;
import org.tldgen.annotations.TldVersion;
import org.tldgen.model.Library;
import org.tldgen.model.LibrarySignature;
import org.tldgen.util.JavadocUtils;

import com.sun.javadoc.AnnotationDesc;
import com.sun.javadoc.PackageDoc;
import com.sun.javadoc.RootDoc;

/**
 * Parse doclet options and create TLD documentation
 * 
 * @author ccoloma
 */
public class TldDoclet {

    private static String DEFAULT_HTML_FOLDER = "build/docs/tlddoc";
    private static String DEFAULT_TLD_FOLDER = "src/main/resources/META-INF";

    /** TLD file display-name */
    private static String displayName;

    /** TLD version */
    private static String version;

    /** TLD file short-name */
    private static String name;

    /** TLD file uri */
    private static String uri;

    /** HTML documentation target directory */
    private static String htmlFolder = DEFAULT_HTML_FOLDER;

    /** TLD target directory */
    private static String tldFolder = DEFAULT_TLD_FOLDER;

    /** TLD File ident */
    private static String indentSpaces;

    /** TLD File license */
    private static String license;

    /** true to format output, false otherwise. Default true */
    private static String formatOutput;

    /** options accepted by this Doclet */
    private static Set<String> options;

    /** for testing purposes */
    public static Library library;

    static {
        options = new TreeSet<String>();
        options.add("displayName");
        options.add("formatOutput");
        options.add("htmlFolder");
        options.add("license");
        options.add("name");
        options.add("tabSpaces");
        options.add("tldFolder");
        options.add("uri");
        options.add("version");

    }

    /**
     * @throws IllegalArgumentException
     *             if illegal or inappropriate TLD filename or creating output
     *             stream.
     * @throws IllegalStateException
     *             if closing a output stream that it is not opened
     */
    public static boolean start(RootDoc root) {
        boolean result = false;
        try {
            DocletOptions options = parseOptions(root.options());
            TldWorker worker = new TldWorker(options);
            if (name != null && uri != null) {
                library = worker.processLibrary(root.classes(), createLibrarySignatureFromCommandLine(), tldFolder,
                        htmlFolder);
                result = true;
            } else {
                for (PackageDoc tagsPackage : root.specifiedPackages()) {
                    AnnotationDesc libraryAnnotation = JavadocUtils.getAnnotation(tagsPackage,
                            org.tldgen.annotations.Library.class);
                    if (libraryAnnotation != null) {
                        library = worker.processLibrary(tagsPackage.allClasses(),
                                createLibrarySignatureFromAnnotation(libraryAnnotation), tldFolder, htmlFolder);

                        // if uri is not specified then use the reverse package name
                        if (library.getLibrarySignature().getUri() == null) {
                            library.getLibrarySignature().setUri("http://" + new String(
                                    ArrayUtilities.reverseTokens(tagsPackage.name().toCharArray(), '.')));
                        }

                        result = true;
                    }
                }
            }
        } finally {
            if (!result) {
                showUsage();
            }
        }
        return result;

    }

    public static LibrarySignature createLibrarySignatureFromCommandLine() {
        LibrarySignature librarySignature = new LibrarySignature();
        librarySignature.setDisplayName(displayName);
        librarySignature.setLicense(convertLicense());
        librarySignature.setShortName(name);
        librarySignature.setUri(uri);
        librarySignature.setVersion(convertVersion());
        return librarySignature;
    }

    public static LibrarySignature createLibrarySignatureFromAnnotation(AnnotationDesc libraryAnnotation) {
        LibrarySignature librarySignature = new LibrarySignature();
        librarySignature.setDescription(getStringAttribute(libraryAnnotation, "description"));
        librarySignature.setDisplayName(getStringAttribute(libraryAnnotation, "displayName"));
        librarySignature.setSmallIcon(getStringAttribute(libraryAnnotation, "smallIcon"));
        librarySignature.setLargeIcon(getStringAttribute(libraryAnnotation, "largeIcon"));
        librarySignature.setShortName(getStringAttribute(libraryAnnotation, "shortName"));
        librarySignature.setUri(getStringAttribute(libraryAnnotation, "uri"));
        license = getEnumAttribute(libraryAnnotation, "license");
        librarySignature.setLicense(convertLicense());
        version = TldVersion.valueOf(getEnumAttribute(libraryAnnotation, "version")).getId();
        librarySignature.setVersion(convertVersion());
        return librarySignature;
    }

    private static License convertLicense() {
        try {
            if (license == null) {
                return License.NONE;
            }
            return License.valueOf(license.toUpperCase());
        } catch (IllegalArgumentException e) {
            try {
                File f = new File(license);
                if (!f.exists() || !f.isFile()) {
                    String licenseNames = StringUtils
                            .join(ArrayUtils.removeElement(License.values(), License.CUSTOM), ", ");
                    throw new IllegalArgumentException("Invalid license. Available licenses are: " + licenseNames
                            + ", or any valid file location.");
                }

                String licenseHeader = FileUtils.readFileToString(f);
                License license = License.CUSTOM;
                license.setLicenseHeader(licenseHeader);
                return license;
            } catch (IOException e1) {
                throw new RuntimeException(e1);
            }
        }
    }

    private static TldVersion convertVersion() {
        TldVersion v = TldVersion.convert(version);
        return v == null ? TldVersion.VERSION_20 : v;
    }

    private static void showUsage() {
        PrintStream out = System.out;
        out.println("Usage: ");
        out.println("tldgen");
        out.println("        -sourcepath {path to java source files}");
        out.println("        -subpackages {tags package name}");
        out.println("");
        out.println("        -displayName {name}");
        out.println("        -formatOutput {true | false}");
        out.println("        -htmlFolder {HTML documentation directory}");
        out.println("        -indentSpaces {number of indent spaces}");
        out.println("        -license {APACHE | GPL | LGPL | MIT | MOZILLA | CC | NONE | [file location]}");
        out.println("        -name {name}");
        out.println("        -tldFolder {TLD folder name}");
        out.println("        -uri {uri name}");
        out.println("        -version {TLD version}");
        out.println("");
        out.println("This doclet accepts the following options:");
        out.println("");
        out.println("  -name: the <name> element of the TLD file");
        out.println("  -uri: the <uri> element of the TLD file");
        out.println("  -displayName (optional): the <display-name> element of the TLD file");
        out.println("  -formatOutput (optional, default true): Indent the generated files.");
        out.println("  -htmlFolder (optional, default " + DEFAULT_HTML_FOLDER + "): the folder \n"
                + "   where HTML documentation will be stored");
        out.println("  -indentSpaces (optional, default 4): spaces used for indenting XML content.");
        out.println("  -license (optional, default NONE): The license to include.");
        out.println("  -tldFolder (optional, default src/main/resources/META-INF/): \n"
                + "   the folder where the TLD file will be stored.");
        out.println("  -version (optional, default 2.0): The TLD version to use.");
        out.println("");
        out.println("If -name or -uri is not present, TldGen will search for @Library annotations in ");
        out.println("the root packages");
        out.println("");
    }

    /**
     * Parse the user options received by this doclet
     * @param userOptions the list of extra options accepted by javadoc
     */
    private static DocletOptions parseOptions(String[][] userOptions) {
        try {
            for (String[] option : userOptions) {
                String fieldName = option[0].substring(1);
                if (options.contains(fieldName)) {
                    Field field = TldDoclet.class.getDeclaredField(fieldName);
                    field.set(null, option[1]);
                }
            }

            DocletOptions options = new DocletOptions();
            if (formatOutput != null) {
                options.withFormatOutput(Boolean.valueOf(formatOutput));
            }
            if (indentSpaces != null) {
                options.withIndentSpaces(indentSpaces);
            }
            if (license != null) {
                options.withLicense(convertLicense());
            }
            if (version != null) {
                options.withVersion(convertVersion());
            }
            return options;
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Return the number of parameters available for each option. See
     * http://java
     * .sun.com/j2se/1.5.0/docs/guide/javadoc/doclet/overview.html#options
     * 
     * @param option
     *            the name of the option parameter
     * @return the number of expected value, 0 if unrecognized
     */
    public static int optionLength(String option) {
        return options.contains("-" + option) ? 0 : 2;
    }

    public static void reset() {
        displayName = version = name = uri = indentSpaces = license = formatOutput = null;
        library = null;

        htmlFolder = DEFAULT_HTML_FOLDER;
        tldFolder = DEFAULT_TLD_FOLDER;

    }

}