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

com.rimerosolutions.ant.git.AntTaskDoclet Maven / Gradle / Ivy

There is a newer version: 1.3.2
Show newest version
/*
 * Copyright 2013, Rimero Solutions
 *
 * 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 com.rimerosolutions.ant.git;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.LanguageVersion;
import com.sun.javadoc.MethodDoc;
import com.sun.javadoc.RootDoc;
import com.sun.tools.doclets.standard.Standard;

/**
 * Quick and very dirty doclet for Ant tasks documentation.
 * Self-Contained for now, no template engine or external dependencies.
 *
 * @author Yves Zoundi
 */
public final class AntTaskDoclet extends Standard {
        private static final String ENCODING_UTF_8 = "UTF-8";
        private static final String ANT_TASK_CLASS_NAME = "org.apache.tools.ant.Task";
        private static String destDir;
        private static String doctitle = "Ant tasks documentation";
        private static String header = "Ant tasks documentation";
        private static String windowtitle = "Ant tasks documentation";
        private static String bottom;
        private static String overview;
        private static final Logger LOG = Logger.getLogger(AntTaskDoclet.class.getName());
        private static final List ELEMENT_PREFIXES = Arrays.asList("create", "add", "addConfigured");
        private static final List ATTRIBUTE_PREFIXES = Arrays.asList("set");
        private static final String TAG_ANTDOC_NOTREQUIRED = "antdoc.notrequired";
        private static Map classDataMap = new HashMap();
        private static final String HTML_INDEX_PAGE = "index.html";
        private static final String HTML_HEADER_PAGE = "header.html";
        private static final String HTML_BODY_PAGE = "body.html";
        private static final String HTML_NAV_PAGE = "nav.html";

        private static final class ElementData {
                String name;
                String description;

                static ElementData fromMethodDoc(MethodDoc methodDoc) {
                        ElementData data = new ElementData();
                        data.name = sanitizeName(methodDoc.name(), ELEMENT_PREFIXES);
                        data.description = methodDoc.commentText();

                        return data;
                }
        }

        private static final class AttributeData {
                String name;
                String description;
                boolean required;

                static AttributeData fromMethodDoc(MethodDoc methodDoc) {
                        AttributeData data = new AttributeData();
                        data.description = methodDoc.commentText();
                        data.required = !(methodDoc.tags(TAG_ANTDOC_NOTREQUIRED).length > 0);
                        data.name = sanitizeName(methodDoc.name(), ATTRIBUTE_PREFIXES);

                        return data;
                }
        }

        private static final class ClassData {
                String qualifiedName;
                String simpleName;
                String description;
                List parentClassDatas = new ArrayList();
                List attributesList = new ArrayList();
                List elementsList = new ArrayList();
                boolean hidden;
        }

        static interface WriterCallback {
                void doWithWriter(Writer w) throws IOException;
        }

        private static void copyFile(File sourceFile, File destFile) throws IOException {
                try (InputStream in = new FileInputStream(sourceFile);
                     OutputStream out = new FileOutputStream(destFile)) {
                        byte[] buf = new byte[4096];
                        int len;
                        while ((len = in.read(buf)) > 0) {
                                out.write(buf, 0, len);
                        }
                }
        }

        public static final boolean start(RootDoc root) {
                readDestDirOption(root.options());

                try {
                        writeContents(root.classes());
                } catch (IOException ioe) {
                        LOG.log(Level.SEVERE, "Ant tasks documentation failed", ioe);
                        return false;
                }

                return true;
        }

        public static void readDestDirOption(String options[][]) {
                for (int i = 0; i < options.length; i++) {
                        String[] opt = options[i];
                        if (opt[0].equals("-d")) {
                                destDir = opt[1];
                        } else if (opt[0].equals("-header")) {
                                header = opt[1];
                        } else if (opt[0].equals("-doctitle")) {
                                doctitle = opt[1];
                        } else if (opt[0].equals("-windowtitle")) {
                                windowtitle = opt[1];
                        } else if (opt[0].equals("-overview")) {
                                overview = opt[1];
                        } else if (opt[0].equals("-bottom")) {
                                bottom = opt[1];
                        }
                }
        }

        private static String sanitizeName(String objectName, List prefixes) {
                String newName = objectName;

                for (String prefix : prefixes) {
                        if (newName.startsWith(prefix)) {
                                String methodName = newName.substring(prefix.length() + 1);
                                return (("" + newName.charAt(prefix.length())).toLowerCase() + methodName).toLowerCase();
                        }
                }

                return newName;

        }

        static void withWriter(File f, WriterCallback wc) throws IOException {
                try (Writer w = new OutputStreamWriter(new FileOutputStream(f), ENCODING_UTF_8)) {
                        wc.doWithWriter(w);
                }
        }

        private static void writeIndexPage() throws IOException {
                withWriter(new File(new File(destDir), HTML_INDEX_PAGE), new WriterCallback() {

                                @Override
                                public void doWithWriter(Writer w) throws IOException {
                                        StringBuilder sb = new StringBuilder();

                                        sb.append("");
                                        sb.append(htmlElement("title", windowtitle));
                                        sb.append("");
                                        sb.append("");
                                        sb.append(" ");
                                        sb.append(" ");
                                        sb.append("");
                                        sb.append("");
                                        sb.append("");
                                        sb.append("");

                                        w.write(sb.toString());
                                }
                        });
        }

        private static void writeHeaderPage() throws IOException {
                withWriter(new File(new File(destDir), HTML_HEADER_PAGE), new WriterCallback() {
                                @Override
                                public void doWithWriter(Writer w) throws IOException {
                                        StringBuilder sb = new StringBuilder();

                                        sb.append("");
                                        sb.append(htmlElement("title", windowtitle));
                                        sb.append("");
                                        sb.append(htmlElement("h1", header));
                                        sb.append("");

                                        w.write(sb.toString());
                                }
                        });
        }

        private static void writeBodyPage() throws IOException {
                if (overview == null) {
                        withWriter(new File(new File(destDir), HTML_BODY_PAGE), new WriterCallback() {
                                        @Override
                                        public void doWithWriter(Writer w) throws IOException {
                                                StringBuilder sb = new StringBuilder();

                                                sb.append("");
                                                sb.append(htmlElement("title", windowtitle));
                                                sb.append("");
                                                sb.append(htmlElement("div", doctitle));
                                                sb.append("");

                                                w.write(sb.toString());
                                        }
                                });
                } else {
                        copyFile(new File(overview), new File(new File(destDir), HTML_BODY_PAGE));
                }
        }

        private static void writeNavPage() throws IOException {
                withWriter(new File(new File(destDir), HTML_NAV_PAGE), new WriterCallback() {
                                @Override
                                public void doWithWriter(Writer w) throws IOException {
                                        StringBuilder sb = new StringBuilder();

                                        sb.append("Nav
"); w.write(sb.toString()); } }); } private static String htmlElement(String tagName, Object contents) { return new StringBuilder(). append('<'). append(tagName). append('>'). append(contents). append("'). toString(); } private static void writeHtmlTasks() throws IOException { Map classDataCopy = new HashMap(classDataMap); for (Map.Entry entry : classDataMap.entrySet()) { String classDocName = entry.getKey(); ClassData classData = entry.getValue(); if (classData.hidden) { continue; } File outputFile = new File(new File(destDir), classDocName + ".html"); OutputStreamWriter w = new OutputStreamWriter(new FileOutputStream(outputFile), ENCODING_UTF_8); StringBuilder header = new StringBuilder(); header.append("classDocName
"); w.write(header.toString()); header = new StringBuilder(); header.append(htmlElement("h1", classData.simpleName)); header.append("
"); header.append(htmlElement("h2", "Description")); header.append(htmlElement("div", classData.description)); w.write(header.toString()); List attributesCopy = new ArrayList(classData.attributesList); List elementsCopy = new ArrayList(classData.elementsList); if (!classData.parentClassDatas.isEmpty()) { for (String parent : classData.parentClassDatas) { attributesCopy.addAll(classDataCopy.get(parent).attributesList); elementsCopy.addAll(classDataCopy.get(parent).elementsList); } } if (!attributesCopy.isEmpty()) { StringBuilder sb = new StringBuilder(); sb.append("

Attributes

"); sb.append(""); sb.append(""); sb.append("").append("").append(""); sb.append(""); for (AttributeData attr : attributesCopy) { sb.append(""); sb.append(htmlElement("td", attr.name)); sb.append(htmlElement("td", attr.description)); sb.append(htmlElement("td", attr.required)); sb.append(""); } sb.append("
NameDescriptionRequired
"); w.write(sb.toString()); } if (!elementsCopy.isEmpty()) { StringBuilder sb = new StringBuilder(); sb.append("

Nested elements

"); sb.append(""); sb.append(""); sb.append("").append(""); sb.append(""); for (ElementData attr : elementsCopy) { sb.append(""); sb.append(htmlElement("td", attr.name)); sb.append(htmlElement("td", attr.description)); sb.append(""); } sb.append("
NameDescription
"); w.write(sb.toString()); } header = new StringBuilder(); header.append("

").append(bottom).append("

"); w.write(header.toString()); header = new StringBuilder(); header.append("
"); w.write(header.toString()); w.flush(); w.close(); } } private static void writeHtmlToOutputDir() throws IOException { writeBodyPage(); writeNavPage(); writeHeaderPage(); writeIndexPage(); writeHtmlTasks(); } private static List collectParentClassesNames(ClassDoc doc) { List parents = new ArrayList(); ClassDoc currentParent = doc.superclass(); while (currentParent != null) { if (currentParent.qualifiedTypeName().equals(ANT_TASK_CLASS_NAME)) { break; } parents.add(currentParent.qualifiedTypeName()); currentParent = currentParent.superclass(); } return parents; } private static boolean isAntTask(ClassDoc classDoc) { ClassDoc currentParent = classDoc.superclass(); while (currentParent != null) { if (currentParent.qualifiedTypeName().equals(ANT_TASK_CLASS_NAME)) { return true; } currentParent = currentParent.superclass(); } return false; } private static void registerClassData(ClassDoc doc) { ClassData data = new ClassData(); Scanner sc = new Scanner(doc.commentText()); data.description = sc.nextLine(); sc.close(); data.qualifiedName = doc.qualifiedTypeName(); data.simpleName = doc.name(); data.hidden = doc.isAbstract(); data.parentClassDatas.addAll(collectParentClassesNames(doc)); for (MethodDoc methodDoc : doc.methods()) { if (!isHiddenMethodDoc(methodDoc)) { if (isTaskAttribute(methodDoc)) { data.attributesList.add(AttributeData.fromMethodDoc(methodDoc)); } else if (isTaskElement(methodDoc)) { data.elementsList.add(ElementData.fromMethodDoc(methodDoc)); } } } classDataMap.put(data.qualifiedName, data); } private static boolean isHiddenMethodDoc(MethodDoc methodDoc) { return methodDoc.isPrivate() || methodDoc.isProtected() || methodDoc.isAbstract(); } private static boolean namePrefixMatches(String name, List prefixes) { for (String prefix : prefixes) { if (name.startsWith(prefix)) { return true; } } return false; } private static boolean isTaskAttribute(MethodDoc methodDoc) { return namePrefixMatches(methodDoc.name(), ATTRIBUTE_PREFIXES); } private static boolean isTaskElement(MethodDoc methodDoc) { return namePrefixMatches(methodDoc.name(), ELEMENT_PREFIXES); } private static void writeContents(ClassDoc[] classDocs) throws IOException { for (ClassDoc classDoc : classDocs) { if (isAntTask(classDoc)) { registerClassData(classDoc); } } writeHtmlToOutputDir(); } public static LanguageVersion languageVersion() { return LanguageVersion.JAVA_1_5; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy