XMLToAPIpublic class XMLToAPI extends Object Creates an API object from an XML file. The API object is the internal
representation of an API.
All methods in this class for populating an API object are static.
See the file LICENSE.txt for copyright details. |
Fields Summary |
---|
private static API | api_The instance of the API object which is populated from the file. | public static boolean | validateXMLIf set, validate the XML which represents an API. By default, this is
not set for reasons of efficiency, and also because if JDiff generated
the XML, it should not need validating. | private static boolean | showExceptionTypesIf set, then store and display the whole qualified name of exceptions.
If not set, then store and display just the name of the exception,
which is shorter, but may not detect when an exception changes class,
but retains the same name. |
Constructors Summary |
---|
private XMLToAPI()Default constructor.
|
Methods Summary |
---|
public static void | addClass(java.lang.String name, java.lang.String parent, boolean isAbstract, Modifiers modifiers)Create a new class and add it to the current package. Called by the XML parser.
api_.currClass_ = new ClassAPI(name, parent, false, isAbstract, modifiers);
api_.currPkg_.classes_.add(api_.currClass_);
String fqName = api_.currPkg_.name_ + "." + name;
ClassAPI caOld = (ClassAPI)api_.classes_.put(fqName, api_.currClass_);
if (caOld != null) {
System.out.println("Warning: duplicate class : " + fqName + " found. Using the first instance only.");
}
| public static void | addCtor(java.lang.String type, Modifiers modifiers)Add a constructor to the current class. Called by the XML parser.
String t = type;
if (t == null)
t = "void";
api_.currCtor_ = new ConstructorAPI(t, modifiers);
api_.currClass_.ctors_.add(api_.currCtor_);
| public static void | addException(java.lang.String name, java.lang.String type, java.lang.String currElement)Add an exception to the current method or constructor.
Called by the XML parser.
String exceptionId = type;
if (type == null || !showExceptionTypes)
exceptionId = name;
if (currElement.compareTo("method") == 0) {
if (api_.currMethod_.exceptions_.compareTo("no exceptions") == 0)
api_.currMethod_.exceptions_ = exceptionId;
else
api_.currMethod_.exceptions_ += ", " + exceptionId;
} else {
if (api_.currCtor_.exceptions_.compareTo("no exceptions") == 0)
api_.currCtor_.exceptions_ = exceptionId;
else
api_.currCtor_.exceptions_ += ", " + exceptionId;
}
| public static void | addField(java.lang.String name, java.lang.String type, boolean isTransient, boolean isVolatile, java.lang.String value, Modifiers modifiers)Add a field to the current class. Called by the XML parser.
String t = type;
if (t == null)
t = "void";
api_.currField_ = new FieldAPI(name, t, isTransient, isVolatile, value, modifiers);
api_.currClass_.fields_.add(api_.currField_);
| public static void | addImplements(java.lang.String name)Add an inherited interface to the current class. Called by the XML
parser.
api_.currClass_.implements_.add(name);
| public static void | addInheritedElements()Add the inherited methods and fields to each class in turn.
Iterator iter = api_.packages_.iterator();
while (iter.hasNext()) {
PackageAPI pkg = (PackageAPI)(iter.next());
Iterator iter2 = pkg.classes_.iterator();
while (iter2.hasNext()) {
ClassAPI cls = (ClassAPI)(iter2.next());
// Look up any inherited classes or interfaces
if (cls.extends_ != null) {
ClassAPI parent = (ClassAPI)api_.classes_.get(cls.extends_);
if (parent != null)
addInheritedElements(cls, parent, cls.extends_);
}
if (cls.implements_.size() != 0) {
Iterator iter3 = cls.implements_.iterator();
while (iter3.hasNext()) {
String implName = (String)(iter3.next());
ClassAPI parent = (ClassAPI)api_.classes_.get(implName);
if (parent != null)
addInheritedElements(cls, parent, implName);
}
}
} //while (iter2.hasNext())
} //while (iter.hasNext())
| public static void | addInheritedElements(ClassAPI child, ClassAPI parent, java.lang.String fqParentName)Add all the inherited methods and fields in the second class to
the first class, marking them as inherited from the second class.
Do not add a method or a field if it is already defined locally.
Only elements at the specified visibility level or
higher appear in the XML file. All that remains to be tested for
a private element, which is never inherited.
If the parent class inherits any classes or interfaces, call this
method recursively with those parents.
if (parent.methods_.size() != 0) {
Iterator iter = parent.methods_.iterator();
while (iter.hasNext()) {
MethodAPI m = (MethodAPI)(iter.next());
// See if it the method is overridden locally
boolean overridden = false;
Iterator iter2 = child.methods_.iterator();
while (iter2.hasNext()) {
MethodAPI localM = (MethodAPI)(iter2.next());
if (localM.name_.compareTo(m.name_) == 0 &&
localM.getSignature().compareTo(m.getSignature()) == 0)
overridden = true;
}
if (!overridden && m.inheritedFrom_ == null &&
m.modifiers_.visibility != null &&
m.modifiers_.visibility.compareTo("private") != 0) {
MethodAPI m2 = new MethodAPI(m);
m2.inheritedFrom_ = fqParentName;
child.methods_.add(m2);
}
}
}
if (parent.fields_.size() != 0) {
Iterator iter = parent.fields_.iterator();
while (iter.hasNext()) {
FieldAPI f = (FieldAPI)(iter.next());
if (child.fields_.indexOf(f) == -1 &&
f.inheritedFrom_ == null &&
f.modifiers_.visibility != null &&
f.modifiers_.visibility.compareTo("private") != 0) {
FieldAPI f2 = new FieldAPI(f);
f2.inheritedFrom_ = fqParentName;
child.fields_.add(f2);
}
}
}
// Look up any inherited classes or interfaces
if (parent.extends_ != null) {
ClassAPI parent2 = (ClassAPI)api_.classes_.get(parent.extends_);
if (parent2 != null)
addInheritedElements(child, parent2, parent.extends_);
}
if (parent.implements_.size() != 0) {
Iterator iter3 = parent.implements_.iterator();
while (iter3.hasNext()) {
String implName = (String)(iter3.next());
ClassAPI parent2 = (ClassAPI)api_.classes_.get(implName);
if (parent2 != null)
addInheritedElements(child, parent2, implName);
}
}
| public static void | addInterface(java.lang.String name, java.lang.String parent, boolean isAbstract, Modifiers modifiers)Add an new interface and add it to the current package. Called by the
XML parser.
api_.currClass_ = new ClassAPI(name, parent, true, isAbstract, modifiers);
api_.currPkg_.classes_.add(api_.currClass_);
| public static void | addMethod(java.lang.String name, java.lang.String returnType, boolean isAbstract, boolean isNative, boolean isSynchronized, Modifiers modifiers)Add a method to the current class. Called by the XML parser.
String rt = returnType;
if (rt == null)
rt = "void";
api_.currMethod_ = new MethodAPI(name, rt, isAbstract, isNative,
isSynchronized, modifiers);
api_.currClass_.methods_.add(api_.currMethod_);
| public static void | addPackage(java.lang.String name)Create a new package and add it to the API. Called by the XML parser.
api_.currPkg_ = new PackageAPI(name);
api_.packages_.add(api_.currPkg_);
| public static void | addParam(java.lang.String name, java.lang.String type)Add a parameter to the current method. Called by the XML parser.
Constuctors have their type (signature) in an attribute, since it
is often shorter and makes parsing a little easier.
String t = type;
if (t == null)
t = "void";
ParamAPI paramAPI = new ParamAPI(name, t);
api_.currMethod_.params_.add(paramAPI);
| public static void | nameAPI(java.lang.String name)Set the name of the API object.
if (name == null) {
System.out.println("Error: no API identifier found in the XML file '" + api_.name_ + "'");
System.exit(3);
}
// Check the given name against the filename currently stored in
// the name_ field
String filename2 = name.replace(' ",'_");
filename2 += ".xml";
if (filename2.compareTo(api_.name_) != 0) {
System.out.println("Warning: API identifier in the XML file (" +
name + ") differs from the name of the file '" +
api_.name_ + "'");
}
api_.name_ = name;
| public static API | readFile(java.lang.String filename, boolean createGlobalComments, java.lang.String apiName)Read the file where the XML representing the API is stored.
// The instance of the API object which is populated from the file.
api_ = new API();
api_.name_ = apiName; // Checked later
try {
XMLReader parser = null;
DefaultHandler handler = new APIHandler(api_, createGlobalComments);
try {
String parserName = System.getProperty("org.xml.sax.driver");
if (parserName == null) {
parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
} else {
// Let the underlying mechanisms try to work out which
// class to instantiate
parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader();
}
} catch (SAXException saxe) {
System.out.println("SAXException: " + saxe);
saxe.printStackTrace();
System.exit(1);
}
if (validateXML) {
parser.setFeature("http://xml.org/sax/features/namespaces", true);
parser.setFeature("http://xml.org/sax/features/validation", true);
parser.setFeature("http://apache.org/xml/features/validation/schema", true);
}
parser.setContentHandler(handler);
parser.setErrorHandler(handler);
parser.parse(new InputSource(new FileInputStream(new File(filename))));
} catch(org.xml.sax.SAXNotRecognizedException snre) {
System.out.println("SAX Parser does not recognize feature: " + snre);
snre.printStackTrace();
System.exit(1);
} catch(org.xml.sax.SAXNotSupportedException snse) {
System.out.println("SAX Parser feature is not supported: " + snse);
snse.printStackTrace();
System.exit(1);
} catch(org.xml.sax.SAXException saxe) {
System.out.println("SAX Exception parsing file '" + filename + "' : " + saxe);
saxe.printStackTrace();
System.exit(1);
} catch(java.io.IOException ioe) {
System.out.println("IOException parsing file '" + filename + "' : " + ioe);
ioe.printStackTrace();
System.exit(1);
}
// Add the inherited methods and fields to each class
addInheritedElements();
return api_;
|
|