196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Projectpackage jdiff;
296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Projectimport java.io.*;
496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Projectimport java.util.*;
596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project/* For SAX parsing in APIHandler */
796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Projectimport org.xml.sax.Attributes;
896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Projectimport org.xml.sax.SAXException;
996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Projectimport org.xml.sax.SAXParseException;
1096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Projectimport org.xml.sax.XMLReader;
1196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Projectimport org.xml.sax.helpers.DefaultHandler;
1296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
1396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project/**
1496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project * Handle the parsing of an XML file and the generation of an API object.
1596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project *
1696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project * See the file LICENSE.txt for copyright details.
1796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project * @author Matthew Doar, mdoar@pobox.com
1896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project */
1996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Projectclass APIHandler extends DefaultHandler {
2096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
2196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** The API object which is populated from the XML file. */
2296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public API api_;
2396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
2496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Default constructor. */
2596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public APIHandler(API api, boolean createGlobalComments) {
2696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        api_ = api;
2796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        createGlobalComments_ = createGlobalComments;
2896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        tagStack = new LinkedList();
290860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young    }
3096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
3196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** If set, then check that each comment is a sentence. */
3296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public static boolean checkIsSentence = false;
3396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
340860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young    /**
3596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Contains the name of the current package element type
3696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * where documentation is being added. Also used as the level
3796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * at which to add documentation into an element, i.e. class-level
3896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * or package-level.
3996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
4096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private String currentElement = null;
4196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
4296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** If set, then create the global list of comments. */
4396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private boolean createGlobalComments_ = false;
4496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
4596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Set if inside a doc element. */
4696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private boolean inDoc = false;
4796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
4896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** The current comment text being assembled. */
4996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private String currentText = null;
5096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
5196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** The current text from deprecation, null if empty. */
5296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private String currentDepText = null;
5396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
540860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young    /**
550860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young     * The stack of SingleComment objects awaiting the comment text
560860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young     * currently being assembled.
5796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
5896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private LinkedList tagStack = null;
5996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
6096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Called at the start of the document. */
6196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void startDocument() {
6296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
630860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young
6496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Called when the end of the document is reached. */
6596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void endDocument() {
6696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (trace)
6796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            api_.dump();
6896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        System.out.println(" finished");
6996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
7096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
7196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Called when a new element is started. */
7296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void startElement(java.lang.String uri, java.lang.String localName,
7396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                             java.lang.String qName, Attributes attributes) {
7496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project	 // The change to JAXP compliance produced this change.
7596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project	if (localName.equals(""))
7696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project	    localName = qName;
7796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (localName.compareTo("api") == 0) {
7896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String apiName = attributes.getValue("name");
7996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String version = attributes.getValue("jdversion"); // Not used yet
8096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            XMLToAPI.nameAPI(apiName);
8196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (localName.compareTo("package") == 0) {
8296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            currentElement = localName;
8396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String pkgName = attributes.getValue("name");
8496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            XMLToAPI.addPackage(pkgName);
8596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (localName.compareTo("class") == 0) {
8696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            currentElement = localName;
8796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String className = attributes.getValue("name");
8896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String parentName = attributes.getValue("extends");
8996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            boolean isAbstract = false;
9096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (attributes.getValue("abstract").compareTo("true") == 0)
9196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                isAbstract = true;
9296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            XMLToAPI.addClass(className, parentName, isAbstract, getModifiers(attributes));
9396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (localName.compareTo("interface") == 0) {
9496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            currentElement = localName;
9596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String className = attributes.getValue("name");
9696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String parentName = attributes.getValue("extends");
9796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            boolean isAbstract = false;
9896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (attributes.getValue("abstract").compareTo("true") == 0)
9996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                isAbstract = true;
10096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            XMLToAPI.addInterface(className, parentName, isAbstract, getModifiers(attributes));
10196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (localName.compareTo("implements") == 0) {
10296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String interfaceName = attributes.getValue("name");
10396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            XMLToAPI.addImplements(interfaceName);
10496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (localName.compareTo("constructor") == 0) {
10596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            currentElement = localName;
1060860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young            String ctorName = attributes.getValue("name");
10796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String ctorType = attributes.getValue("type");
1080860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young            XMLToAPI.addCtor(ctorName, ctorType, getModifiers(attributes));
10996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (localName.compareTo("method") == 0) {
11096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            currentElement = localName;
11196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String methodName = attributes.getValue("name");
11296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String returnType = attributes.getValue("return");
11396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            boolean isAbstract = false;
11496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (attributes.getValue("abstract").compareTo("true") == 0)
11596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                isAbstract = true;
11696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            boolean isNative = false;
11796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (attributes.getValue("native").compareTo("true") == 0)
11896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                isNative = true;
11996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            boolean isSynchronized = false;
12096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (attributes.getValue("synchronized").compareTo("true") == 0)
12196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                isSynchronized = true;
1220860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young            XMLToAPI.addMethod(methodName, returnType, isAbstract, isNative,
12396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                               isSynchronized, getModifiers(attributes));
12496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (localName.compareTo("field") == 0) {
12596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            currentElement = localName;
12696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String fieldName = attributes.getValue("name");
12796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String fieldType = attributes.getValue("type");
12896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            boolean isTransient = false;
12996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (attributes.getValue("transient").compareTo("true") == 0)
13096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                isTransient = true;
13196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            boolean isVolatile = false;
13296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (attributes.getValue("volatile").compareTo("true") == 0)
13396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                isVolatile = true;
13496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String value = attributes.getValue("value");
1350860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young            XMLToAPI.addField(fieldName, fieldType, isTransient, isVolatile,
13696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                              value, getModifiers(attributes));
1370860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young        } else if (localName.compareTo("param") == 0 || localName.compareTo("parameter") == 0) {
13896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String paramName = attributes.getValue("name");
13996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String paramType = attributes.getValue("type");
1400860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young            XMLToAPI.addParam(paramName, paramType, currentElement.compareTo("constructor") == 0);
14196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (localName.compareTo("exception") == 0) {
14296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String paramName = attributes.getValue("name");
14396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String paramType = attributes.getValue("type");
14496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            XMLToAPI.addException(paramName, paramType, currentElement);
14596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (localName.compareTo("doc") == 0) {
14696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            inDoc = true;
14796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            currentText = null;
14896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else {
14996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (inDoc) {
15096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                // Start of an element, probably an HTML element
15196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                addStartTagToText(localName, attributes);
15296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            } else {
15396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                System.out.println("Error: unknown element type: " + localName);
15496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                System.exit(-1);
15596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
15696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
15796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
1580860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young
15996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Called when the end of an element is reached. */
1600860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young    public void endElement(java.lang.String uri, java.lang.String localName,
16196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                           java.lang.String qName) {
1620860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young        if (localName.equals(""))
1630860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young            localName = qName;
16496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Deal with the end of doc blocks
16596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (localName.compareTo("doc") == 0) {
16696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            inDoc = false;
16796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // Add the assembled comment text to the appropriate current
16896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // program element, as determined by currentElement.
16996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            addTextToComments();
17096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (inDoc) {
17196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // An element was found inside the HTML text
17296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            addEndTagToText(localName);
1730860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young        } else if (currentElement.compareTo("constructor") == 0 &&
17496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                   localName.compareTo("constructor") == 0) {
17596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            currentElement = "class";
1760860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young        } else if (currentElement.compareTo("method") == 0 &&
17796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                   localName.compareTo("method") == 0) {
17896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            currentElement = "class";
1790860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young        } else if (currentElement.compareTo("field") == 0 &&
18096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                   localName.compareTo("field") == 0) {
18196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            currentElement = "class";
18296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (currentElement.compareTo("class") == 0 ||
18396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                   currentElement.compareTo("interface") == 0) {
18496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // Feature request 510307 and bug 517383: duplicate comment ids.
1850860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young            // The end of a member element leaves the currentElement at the
18696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // "class" level, but the next class may in fact be an interface
18796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // and so the currentElement here will be "interface".
1880860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young            if (localName.compareTo("class") == 0 ||
18996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                localName.compareTo("interface") == 0) {
19096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                currentElement = "package";
19196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
19296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
19396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
19496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
19596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Called to process text. */
19696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void characters(char[] ch, int start, int length) {
19796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project         if (inDoc) {
19896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String chunk = new String(ch, start, length);
19996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (currentText == null)
20096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                currentText = chunk;
20196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            else
20296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                currentText += chunk;
20396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project         }
20496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
20596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
2060860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young    /**
20796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * Trim the current text, check it is a sentence and add it to the
2080860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young     * current program element.
20996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
21096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void addTextToComments() {
21196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Eliminate any whitespace at each end of the text.
2120860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young        currentText = currentText.trim();
21396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Convert any @link tags to HTML links.
21496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (convertAtLinks) {
2150860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young            currentText = Comments.convertAtLinks(currentText, currentElement,
21696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                                                  api_.currPkg_, api_.currClass_);
21796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
21896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Check that it is a sentence
2190860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young        if (checkIsSentence && !currentText.endsWith(".") &&
22096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            currentText.compareTo(Comments.placeHolderText) != 0) {
22196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            System.out.println("Warning: text of comment does not end in a period: " + currentText);
22296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
2230860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young        // The construction of the commentID assumes that the
22496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // documentation is the final element to be parsed. The format matches
22596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // the format used in the report generator to look up comments in the
22696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // the existingComments object.
22796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String commentID = null;
22896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Add this comment to the current API element.
22996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (currentElement.compareTo("package") == 0) {
23096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            api_.currPkg_.doc_ = currentText;
23196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            commentID = api_.currPkg_.name_;
23296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (currentElement.compareTo("class") == 0 ||
23396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                   currentElement.compareTo("interface") == 0) {
23496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            api_.currClass_.doc_ = currentText;
23596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            commentID = api_.currPkg_.name_ + "." + api_.currClass_.name_;
23696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (currentElement.compareTo("constructor") == 0) {
23796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            api_.currCtor_.doc_ = currentText;
23896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            commentID = api_.currPkg_.name_ + "." + api_.currClass_.name_ +
23996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                ".ctor_changed(";
2400860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young            if (api_.currCtor_.getSignature().compareTo("void") == 0)
24196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                commentID = commentID + ")";
24296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            else
2430860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young                commentID = commentID + api_.currCtor_.getSignature() + ")";
24496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (currentElement.compareTo("method") == 0) {
24596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            api_.currMethod_.doc_ = currentText;
24696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            commentID = api_.currPkg_.name_ + "." + api_.currClass_.name_ +
2470860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young                "." + api_.currMethod_.name_ + "_changed(" +
24896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                api_.currMethod_.getSignature() + ")";
24996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (currentElement.compareTo("field") == 0) {
25096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            api_.currField_.doc_ = currentText;
25196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            commentID = api_.currPkg_.name_ + "." + api_.currClass_.name_ +
25296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                "." + api_.currField_.name_;
2530860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young        }
25496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Add to the list of possible comments for use when an
25596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // element has changed (not removed or added).
25696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (createGlobalComments_ && commentID != null) {
25796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String ct = currentText;
2580860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young            // Use any deprecation text as the possible comment, ignoring
25996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            // any other comment text.
26096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (currentDepText != null) {
26196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                ct = currentDepText;
26296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                currentDepText = null; // Never reuse it. Bug 469794
26396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
26496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String ctOld = (String)(Comments.allPossibleComments.put(commentID, ct));
26596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            if (ctOld != null) {
26696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                System.out.println("Error: duplicate comment id: " + commentID);
26796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project                System.exit(5);
26896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            }
26996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
27096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
27196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
2720860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young    /**
2730860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young     * Add the start tag to the current comment text.
27496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
27596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void addStartTagToText(String localName, Attributes attributes) {
27696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Need to insert the HTML tag into the current text
27796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String currentHTMLTag = localName;
27896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Save the tag in a stack
27996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        tagStack.add(currentHTMLTag);
28096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String tag = "<" + currentHTMLTag;
28196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Now add all the attributes into the current text
28296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        int len = attributes.getLength();
28396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        for (int i = 0; i < len; i++) {
28496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String name = attributes.getLocalName(i);
28596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            String value = attributes.getValue(i);
28696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            tag += " " + name + "=\"" + value+ "\"";
28796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
28896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
28996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // End the tag
29096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (Comments.isMinimizedTag(currentHTMLTag)) {
29196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            tag += "/>";
29296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else {
29396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            tag += ">";
29496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
29596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Now insert the HTML tag into the current text
29696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (currentText == null)
29796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            currentText = tag;
29896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        else
29996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            currentText += tag;
30096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
30196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
3020860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young    /**
3030860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young     * Add the end tag to the current comment text.
30496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
30596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void addEndTagToText(String localName) {
30696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        // Close the current HTML tag
30796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String currentHTMLTag = (String)(tagStack.removeLast());
30896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (!Comments.isMinimizedTag(currentHTMLTag))
30996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            currentText += "</" + currentHTMLTag + ">";
31096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
31196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
31296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Extra modifiers which are common to all program elements. */
31396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public Modifiers getModifiers(Attributes attributes) {
31496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        Modifiers modifiers = new Modifiers();
31596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        modifiers.isStatic = false;
31696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (attributes.getValue("static").compareTo("true") == 0)
31796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            modifiers.isStatic = true;
31896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        modifiers.isFinal = false;
31996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (attributes.getValue("final").compareTo("true") == 0)
32096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            modifiers.isFinal = true;
32196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        modifiers.isDeprecated = false;
32296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        String cdt = attributes.getValue("deprecated");
32396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        if (cdt.compareTo("not deprecated") == 0) {
32496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            modifiers.isDeprecated = false;
32596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            currentDepText = null;
32696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else if (cdt.compareTo("deprecated, no comment") == 0) {
32796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            modifiers.isDeprecated = true;
32896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            currentDepText = null;
32996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        } else {
33096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            modifiers.isDeprecated = true;
33196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project            currentDepText = API.showHTMLTags(cdt);
33296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        }
33396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        modifiers.visibility = attributes.getValue("visibility");
33496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        return modifiers;
33596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
33696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
33796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void warning(SAXParseException e) {
33896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        System.out.println("Warning (" + e.getLineNumber() + "): parsing XML API file:" + e);
33996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        e.printStackTrace();
34096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
34196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
34296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void error(SAXParseException e) {
34396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        System.out.println("Error (" + e.getLineNumber() + "): parsing XML API file:" + e);
34496b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        e.printStackTrace();
34596b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        System.exit(1);
34696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    }
3470860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young
34896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    public void fatalError(SAXParseException e) {
34996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        System.out.println("Fatal Error (" + e.getLineNumber() + "): parsing XML API file:" + e);
35096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        e.printStackTrace();
35196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project        System.exit(1);
3520860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young    }
35396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
3540860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young    /**
3550860aaa8b3cd01b42407009ffe4e0697ef0c1356C. Sean Young     * If set, then attempt to convert @link tags to HTML links.
35696b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     * A few of the HTML links may be broken links.
35796b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project     */
35896b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private static boolean convertAtLinks = true;
35996b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
36096b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    /** Set to enable increased logging verbosity for debugging. */
36196b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project    private static boolean trace = false;
36296b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project
36396b00fec6cd6068c1c5ae09de0358340c0ec499eThe Android Open Source Project}
364