APIHandlerpublic class APIHandler extends DefaultHandler Handle the parsing of an XML file and the generation of an API object.
See the file LICENSE.txt for copyright details. |
Fields Summary |
---|
public API | api_The API object which is populated from the XML file. | public static boolean | checkIsSentenceIf set, then check that each comment is a sentence. | private String | currentElementContains the name of the current package element type
where documentation is being added. Also used as the level
at which to add documentation into an element, i.e. class-level
or package-level. | private boolean | createGlobalComments_If set, then create the global list of comments. | private boolean | inDocSet if inside a doc element. | private String | currentTextThe current comment text being assembled. | private String | currentDepTextThe current text from deprecation, null if empty. | private LinkedList | tagStackThe stack of SingleComment objects awaiting the comment text
currently being assembled. | private static boolean | convertAtLinksIf set, then attempt to convert @link tags to HTML links.
A few of the HTML links may be broken links. | private static boolean | traceSet to enable increased logging verbosity for debugging. |
Constructors Summary |
---|
public APIHandler(API api, boolean createGlobalComments)Default constructor.
api_ = api;
createGlobalComments_ = createGlobalComments;
tagStack = new LinkedList();
|
Methods Summary |
---|
public void | addEndTagToText(java.lang.String localName)Add the end tag to the current comment text.
// Close the current HTML tag
String currentHTMLTag = (String)(tagStack.removeLast());
if (!Comments.isMinimizedTag(currentHTMLTag))
currentText += "</" + currentHTMLTag + ">";
| public void | addStartTagToText(java.lang.String localName, org.xml.sax.Attributes attributes)Add the start tag to the current comment text.
// Need to insert the HTML tag into the current text
String currentHTMLTag = localName;
// Save the tag in a stack
tagStack.add(currentHTMLTag);
String tag = "<" + currentHTMLTag;
// Now add all the attributes into the current text
int len = attributes.getLength();
for (int i = 0; i < len; i++) {
String name = attributes.getLocalName(i);
String value = attributes.getValue(i);
tag += " " + name + "=\"" + value+ "\"";
}
// End the tag
if (Comments.isMinimizedTag(currentHTMLTag)) {
tag += "/>";
} else {
tag += ">";
}
// Now insert the HTML tag into the current text
if (currentText == null)
currentText = tag;
else
currentText += tag;
| public void | addTextToComments()Trim the current text, check it is a sentence and add it to the
current program element.
// Eliminate any whitespace at each end of the text.
currentText = currentText.trim();
// Convert any @link tags to HTML links.
if (convertAtLinks) {
currentText = Comments.convertAtLinks(currentText, currentElement,
api_.currPkg_, api_.currClass_);
}
// Check that it is a sentence
if (checkIsSentence && !currentText.endsWith(".") &&
currentText.compareTo(Comments.placeHolderText) != 0) {
System.out.println("Warning: text of comment does not end in a period: " + currentText);
}
// The construction of the commentID assumes that the
// documentation is the final element to be parsed. The format matches
// the format used in the report generator to look up comments in the
// the existingComments object.
String commentID = null;
// Add this comment to the current API element.
if (currentElement.compareTo("package") == 0) {
api_.currPkg_.doc_ = currentText;
commentID = api_.currPkg_.name_;
} else if (currentElement.compareTo("class") == 0 ||
currentElement.compareTo("interface") == 0) {
api_.currClass_.doc_ = currentText;
commentID = api_.currPkg_.name_ + "." + api_.currClass_.name_;
} else if (currentElement.compareTo("constructor") == 0) {
api_.currCtor_.doc_ = currentText;
commentID = api_.currPkg_.name_ + "." + api_.currClass_.name_ +
".ctor_changed(";
if (api_.currCtor_.type_.compareTo("void") == 0)
commentID = commentID + ")";
else
commentID = commentID + api_.currCtor_.type_ + ")";
} else if (currentElement.compareTo("method") == 0) {
api_.currMethod_.doc_ = currentText;
commentID = api_.currPkg_.name_ + "." + api_.currClass_.name_ +
"." + api_.currMethod_.name_ + "_changed(" +
api_.currMethod_.getSignature() + ")";
} else if (currentElement.compareTo("field") == 0) {
api_.currField_.doc_ = currentText;
commentID = api_.currPkg_.name_ + "." + api_.currClass_.name_ +
"." + api_.currField_.name_;
}
// Add to the list of possible comments for use when an
// element has changed (not removed or added).
if (createGlobalComments_ && commentID != null) {
String ct = currentText;
// Use any deprecation text as the possible comment, ignoring
// any other comment text.
if (currentDepText != null) {
ct = currentDepText;
currentDepText = null; // Never reuse it. Bug 469794
}
String ctOld = (String)(Comments.allPossibleComments.put(commentID, ct));
if (ctOld != null) {
System.out.println("Error: duplicate comment id: " + commentID);
System.exit(5);
}
}
| public void | characters(char[] ch, int start, int length)Called to process text.
if (inDoc) {
String chunk = new String(ch, start, length);
if (currentText == null)
currentText = chunk;
else
currentText += chunk;
}
| public void | endDocument()Called when the end of the document is reached.
if (trace)
api_.dump();
System.out.println(" finished");
| public void | endElement(java.lang.String uri, java.lang.String localName, java.lang.String qName)Called when the end of an element is reached.
if (localName.equals(""))
localName = qName;
// Deal with the end of doc blocks
if (localName.compareTo("doc") == 0) {
inDoc = false;
// Add the assembled comment text to the appropriate current
// program element, as determined by currentElement.
addTextToComments();
} else if (inDoc) {
// An element was found inside the HTML text
addEndTagToText(localName);
} else if (currentElement.compareTo("constructor") == 0 &&
localName.compareTo("constructor") == 0) {
currentElement = "class";
} else if (currentElement.compareTo("method") == 0 &&
localName.compareTo("method") == 0) {
currentElement = "class";
} else if (currentElement.compareTo("field") == 0 &&
localName.compareTo("field") == 0) {
currentElement = "class";
} else if (currentElement.compareTo("class") == 0 ||
currentElement.compareTo("interface") == 0) {
// Feature request 510307 and bug 517383: duplicate comment ids.
// The end of a member element leaves the currentElement at the
// "class" level, but the next class may in fact be an interface
// and so the currentElement here will be "interface".
if (localName.compareTo("class") == 0 ||
localName.compareTo("interface") == 0) {
currentElement = "package";
}
}
| public void | error(org.xml.sax.SAXParseException e)
System.out.println("Error (" + e.getLineNumber() + "): parsing XML API file:" + e);
e.printStackTrace();
System.exit(1);
| public void | fatalError(org.xml.sax.SAXParseException e)
System.out.println("Fatal Error (" + e.getLineNumber() + "): parsing XML API file:" + e);
e.printStackTrace();
System.exit(1);
| public Modifiers | getModifiers(org.xml.sax.Attributes attributes)Extra modifiers which are common to all program elements.
Modifiers modifiers = new Modifiers();
modifiers.isStatic = false;
if (attributes.getValue("static").compareTo("true") == 0)
modifiers.isStatic = true;
modifiers.isFinal = false;
if (attributes.getValue("final").compareTo("true") == 0)
modifiers.isFinal = true;
modifiers.isDeprecated = false;
String cdt = attributes.getValue("deprecated");
if (cdt.compareTo("not deprecated") == 0) {
modifiers.isDeprecated = false;
currentDepText = null;
} else if (cdt.compareTo("deprecated, no comment") == 0) {
modifiers.isDeprecated = true;
currentDepText = null;
} else {
modifiers.isDeprecated = true;
currentDepText = API.showHTMLTags(cdt);
}
modifiers.visibility = attributes.getValue("visibility");
return modifiers;
| public void | startDocument()Called at the start of the document.
| public void | startElement(java.lang.String uri, java.lang.String localName, java.lang.String qName, org.xml.sax.Attributes attributes)Called when a new element is started.
// The change to JAXP compliance produced this change.
if (localName.equals(""))
localName = qName;
if (localName.compareTo("api") == 0) {
String apiName = attributes.getValue("name");
String version = attributes.getValue("jdversion"); // Not used yet
XMLToAPI.nameAPI(apiName);
} else if (localName.compareTo("package") == 0) {
currentElement = localName;
String pkgName = attributes.getValue("name");
XMLToAPI.addPackage(pkgName);
} else if (localName.compareTo("class") == 0) {
currentElement = localName;
String className = attributes.getValue("name");
String parentName = attributes.getValue("extends");
boolean isAbstract = false;
if (attributes.getValue("abstract").compareTo("true") == 0)
isAbstract = true;
XMLToAPI.addClass(className, parentName, isAbstract, getModifiers(attributes));
} else if (localName.compareTo("interface") == 0) {
currentElement = localName;
String className = attributes.getValue("name");
String parentName = attributes.getValue("extends");
boolean isAbstract = false;
if (attributes.getValue("abstract").compareTo("true") == 0)
isAbstract = true;
XMLToAPI.addInterface(className, parentName, isAbstract, getModifiers(attributes));
} else if (localName.compareTo("implements") == 0) {
String interfaceName = attributes.getValue("name");
XMLToAPI.addImplements(interfaceName);
} else if (localName.compareTo("constructor") == 0) {
currentElement = localName;
String ctorType = attributes.getValue("type");
XMLToAPI.addCtor(ctorType, getModifiers(attributes));
} else if (localName.compareTo("method") == 0) {
currentElement = localName;
String methodName = attributes.getValue("name");
String returnType = attributes.getValue("return");
boolean isAbstract = false;
if (attributes.getValue("abstract").compareTo("true") == 0)
isAbstract = true;
boolean isNative = false;
if (attributes.getValue("native").compareTo("true") == 0)
isNative = true;
boolean isSynchronized = false;
if (attributes.getValue("synchronized").compareTo("true") == 0)
isSynchronized = true;
XMLToAPI.addMethod(methodName, returnType, isAbstract, isNative,
isSynchronized, getModifiers(attributes));
} else if (localName.compareTo("field") == 0) {
currentElement = localName;
String fieldName = attributes.getValue("name");
String fieldType = attributes.getValue("type");
boolean isTransient = false;
if (attributes.getValue("transient").compareTo("true") == 0)
isTransient = true;
boolean isVolatile = false;
if (attributes.getValue("volatile").compareTo("true") == 0)
isVolatile = true;
String value = attributes.getValue("value");
XMLToAPI.addField(fieldName, fieldType, isTransient, isVolatile,
value, getModifiers(attributes));
} else if (localName.compareTo("param") == 0) {
String paramName = attributes.getValue("name");
String paramType = attributes.getValue("type");
XMLToAPI.addParam(paramName, paramType);
} else if (localName.compareTo("exception") == 0) {
String paramName = attributes.getValue("name");
String paramType = attributes.getValue("type");
XMLToAPI.addException(paramName, paramType, currentElement);
} else if (localName.compareTo("doc") == 0) {
inDoc = true;
currentText = null;
} else {
if (inDoc) {
// Start of an element, probably an HTML element
addStartTagToText(localName, attributes);
} else {
System.out.println("Error: unknown element type: " + localName);
System.exit(-1);
}
}
| public void | warning(org.xml.sax.SAXParseException e)
System.out.println("Warning (" + e.getLineNumber() + "): parsing XML API file:" + e);
e.printStackTrace();
|
|