10aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato/*
20aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato * Copyright (C) 2010 Google Inc.
30aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato *
40aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
50aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato * you may not use this file except in compliance with the License.
60aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato * You may obtain a copy of the License at
70aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato *
80aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato * http://www.apache.org/licenses/LICENSE-2.0
90aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato *
100aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato * Unless required by applicable law or agreed to in writing, software
110aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
120aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato * See the License for the specific language governing permissions and
140aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato * limitations under the License.
150aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato */
160aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato
170aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onoratopackage com.google.doclava.apicheck;
180aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato
190aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onoratoimport com.google.doclava.AnnotationInstanceInfo;
200aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onoratoimport com.google.doclava.ClassInfo;
210aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onoratoimport com.google.doclava.Converter;
220aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onoratoimport com.google.doclava.FieldInfo;
230aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onoratoimport com.google.doclava.MethodInfo;
240aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onoratoimport com.google.doclava.PackageInfo;
250aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onoratoimport com.google.doclava.ParameterInfo;
260aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onoratoimport com.google.doclava.SourcePositionInfo;
270aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onoratoimport com.google.doclava.TypeInfo;
28d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinimport com.sun.javadoc.ClassDoc;
290aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato
300aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onoratoimport org.xml.sax.Attributes;
310aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onoratoimport org.xml.sax.InputSource;
320aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onoratoimport org.xml.sax.XMLReader;
330aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onoratoimport org.xml.sax.helpers.DefaultHandler;
340aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onoratoimport org.xml.sax.helpers.XMLReaderFactory;
350aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato
36d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinimport java.io.InputStream;
37d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinimport java.util.ArrayList;
38d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sappersteinimport java.util.Stack;
39d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein
400aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onoratoclass XmlApiFile extends DefaultHandler {
410aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato
420aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato  private ApiInfo mApi;
430aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato  private PackageInfo mCurrentPackage;
440aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato  private ClassInfo mCurrentClass;
450aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato  private AbstractMethodInfo mCurrentMethod;
460aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato  private Stack<ClassInfo> mClassScope = new Stack<ClassInfo>();
470aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato
480aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato  public static ApiInfo parseApi(InputStream xmlStream) throws ApiParseException {
490aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato    try {
500aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      XMLReader xmlreader = XMLReaderFactory.createXMLReader();
510aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      XmlApiFile handler = new XmlApiFile();
520aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      xmlreader.setContentHandler(handler);
530aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      xmlreader.setErrorHandler(handler);
540aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      xmlreader.parse(new InputSource(xmlStream));
550aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      ApiInfo apiInfo = handler.getApi();
560aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      apiInfo.resolveSuperclasses();
570aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      apiInfo.resolveInterfaces();
580aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      return apiInfo;
590aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato    } catch (Exception e) {
600aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      throw new ApiParseException("Error parsing API", e);
610aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato    }
620aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato  }
630aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato
640aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato  private XmlApiFile() {
650aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato    super();
660aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato    mApi = new ApiInfo();
670aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato  }
680aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato
690aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato  @Override
700aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato  public void startElement(String uri, String localName, String qName, Attributes attributes) {
710aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato    if (qName.equals("package")) {
720aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      mCurrentPackage =
730aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato          new PackageInfo(attributes.getValue("name"), SourcePositionInfo.fromXml(attributes
740aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato              .getValue("source")));
750aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato    } else if (qName.equals("class") || qName.equals("interface")) {
760aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      // push the old outer scope for later recovery, then set
770aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      // up the new current class object
780aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      mClassScope.push(mCurrentClass);
790aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato
800aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      ClassDoc classDoc = null;
810aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      String rawCommentText = "";
820aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      SourcePositionInfo position = SourcePositionInfo.fromXml(attributes.getValue("source"));
830aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      String visibility = attributes.getValue("visibility");
840aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isPublic = "public".equals(visibility);
850aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isProtected = "protected".equals(visibility);
860aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isPrivate = "private".equals(visibility);
870aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isPackagePrivate = !isPublic && !isPrivate && !isProtected;
880aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isStatic = Boolean.valueOf(attributes.getValue("static"));
890aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isInterface = qName.equals("interface");
900aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isAbstract = Boolean.valueOf(attributes.getValue("abstract"));
910aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isOrdinaryClass = qName.equals("class");
920aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isException = false; // TODO: check hierarchy for java.lang.Exception
930aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isError = false; // TODO: not sure.
940aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isEnum = false; // TODO: not sure.
950aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isAnnotation = false; // TODO: not sure.
960aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isFinal = Boolean.valueOf(attributes.getValue("final"));
970aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isIncluded = false;
980aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      String name = attributes.getValue("name");
990aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      String qualifiedName = qualifiedName(mCurrentPackage.name(), name, mCurrentClass);
1000aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      String qualifiedTypeName = null; // TODO: not sure
1010aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isPrimitive = false;
1020aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato
1030aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      mCurrentClass =
1040aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato          new ClassInfo(classDoc, rawCommentText, position, isPublic, isProtected,
1050aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato          isPackagePrivate, isPrivate, isStatic, isInterface, isAbstract, isOrdinaryClass,
1060aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato          isException, isError, isEnum, isAnnotation, isFinal, isIncluded, name, qualifiedName,
1070aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato          qualifiedTypeName, isPrimitive);
1080aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato
109040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato      mCurrentClass.setDeprecated("deprecated".equals(attributes.getValue("deprecated")));
1100aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      mCurrentClass.setContainingPackage(mCurrentPackage);
1110aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      String superclass = attributes.getValue("extends");
1120aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      if (superclass == null && !isInterface && !"java.lang.Object".equals(qualifiedName)) {
1130aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato        throw new AssertionError("no superclass known for class " + name);
1140aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      }
1150aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato
1160aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      // Resolve superclass after .xml completely parsed.
1170aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      mApi.mapClassToSuper(mCurrentClass, superclass);
1180aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato
1190aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      TypeInfo typeInfo = Converter.obtainTypeFromString(qualifiedName) ;
1200aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      mCurrentClass.setTypeInfo(typeInfo);
121d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      mCurrentClass.setAnnotations(new ArrayList<AnnotationInstanceInfo>());
1220aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato    } else if (qName.equals("method")) {
1230aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      String rawCommentText = "";
124d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      ArrayList<TypeInfo> typeParameters = new ArrayList<TypeInfo>();
1250aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      String name = attributes.getValue("name");
1260aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      String signature = null; // TODO
1270aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      ClassInfo containingClass = mCurrentClass;
1280aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      ClassInfo realContainingClass = mCurrentClass;
1290aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      String visibility = attributes.getValue("visibility");
1300aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isPublic = "public".equals(visibility);
1310aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isProtected = "protected".equals(visibility);
1320aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isPrivate = "private".equals(visibility);
1330aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isPackagePrivate = !isPublic && !isPrivate && !isProtected;
1340aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isFinal = Boolean.valueOf(attributes.getValue("final"));
1350aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isStatic = Boolean.valueOf(attributes.getValue("static"));
1360aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isSynthetic = false; // TODO
1370aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isAbstract = Boolean.valueOf(attributes.getValue("abstract"));
1380aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isSynchronized = Boolean.valueOf(attributes.getValue("synchronized"));
1390aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isNative = Boolean.valueOf(attributes.getValue("native"));
1400aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isAnnotationElement = false; // TODO
1410aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      String kind = qName;
1420aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      String flatSignature = null; // TODO
1430aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      MethodInfo overriddenMethod = null; // TODO
1440aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      TypeInfo returnType = Converter.obtainTypeFromString(attributes.getValue("return"));
145d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      ArrayList<ParameterInfo> parameters = new ArrayList<ParameterInfo>();
146d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      ArrayList<ClassInfo> thrownExceptions = new ArrayList<ClassInfo>();
1470aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      SourcePositionInfo position = SourcePositionInfo.fromXml(attributes.getValue("source"));
148d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein      ArrayList<AnnotationInstanceInfo> annotations = new ArrayList<AnnotationInstanceInfo>(); // TODO
1490aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato
1500aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      mCurrentMethod =
1510aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato          new MethodInfo(rawCommentText, typeParameters, name, signature, containingClass,
1520aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato          realContainingClass, isPublic, isProtected, isPackagePrivate, isPrivate, isFinal,
1530aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato          isStatic, isSynthetic, isAbstract, isSynchronized, isNative, isAnnotationElement, kind,
1540aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato          flatSignature, overriddenMethod, returnType, parameters, thrownExceptions, position,
1550aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato          annotations);
1560aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato
1570aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      mCurrentMethod.setDeprecated("deprecated".equals(attributes.getValue("deprecated")));
1580aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato    } else if (qName.equals("constructor")) {
159040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato      final boolean pub = "public".equals(attributes.getValue("visibility"));
160040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato      final boolean prot = "protected".equals(attributes.getValue("visibility"));
161040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato      final boolean pkgpriv = "".equals(attributes.getValue("visibility"));
1620aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      mCurrentMethod =
163d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein         new MethodInfo(""/*rawCommentText*/, new ArrayList<TypeInfo>()/*typeParameters*/,
164040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato              attributes.getValue("name"), null/*signature*/, mCurrentClass, mCurrentClass,
165040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato              pub, prot, pkgpriv, false/*isPrivate*/, false/*isFinal*/, false/*isStatic*/,
166040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato              false/*isSynthetic*/, false/*isAbstract*/, false/*isSynthetic*/, false/*isNative*/,
167040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato              false /*isAnnotationElement*/, "constructor", null/*flatSignature*/,
168d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein              null/*overriddenMethod*/, mCurrentClass.asTypeInfo(), new ArrayList<ParameterInfo>(),
169d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein              new ArrayList<ClassInfo>()/*thrownExceptions*/,
170040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato              SourcePositionInfo.fromXml(attributes.getValue("source")),
171d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein              new ArrayList<AnnotationInstanceInfo>()/*annotations*/);
172040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato      mCurrentMethod.setDeprecated("deprecated".equals(attributes.getValue("deprecated")));
1730aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato    } else if (qName.equals("field")) {
1740aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      String visibility = attributes.getValue("visibility");
1750aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isPublic = visibility.equals("public");
1760aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isProtected = visibility.equals("protected");
1770aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isPrivate = visibility.equals("private");
1780aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isPackagePrivate = visibility.equals("");
1790aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      String typeName = attributes.getValue("type");
1800aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      TypeInfo type = Converter.obtainTypeFromString(typeName);
1810aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato
182040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato      Object value;
183040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato      try {
184040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato          value = ApiFile.parseValue(typeName, attributes.getValue("value"));
185040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato      } catch (ApiParseException ex) {
186040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato          throw new RuntimeException(ex);
187040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato      }
188040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato
1890aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      FieldInfo fInfo =
1900aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato          new FieldInfo(attributes.getValue("name"), mCurrentClass, mCurrentClass, isPublic,
1910aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato          isProtected, isPackagePrivate, isPrivate, Boolean.valueOf(attributes.getValue("final")),
1920aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato          Boolean.valueOf(attributes.getValue("static")), Boolean.valueOf(attributes.
1930aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato          getValue("transient")), Boolean.valueOf(attributes.getValue("volatile")), false,
194040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato          type, "", value, SourcePositionInfo.fromXml(attributes.getValue("source")),
195d6eaacbb9eb56763d38a3815fc509b92ed98a585Andrew Sapperstein          new ArrayList<AnnotationInstanceInfo>());
1960aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato
1970aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      fInfo.setDeprecated("deprecated".equals(attributes.getValue("deprecated")));
1980aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      mCurrentClass.addField(fInfo);
1990aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato    } else if (qName.equals("parameter")) {
2000aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      String name = attributes.getValue("name");
2010aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      String typeName = attributes.getValue("type");
2020aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      TypeInfo type = Converter.obtainTypeFromString(typeName);
2030aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      boolean isVarArg = typeName.endsWith("...");
2040aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      SourcePositionInfo position = null;
2050aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato
2060aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      mCurrentMethod.addParameter(new ParameterInfo(name, typeName, type, isVarArg, position));
2070aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      mCurrentMethod.setVarargs(isVarArg);
2080aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato    } else if (qName.equals("exception")) {
2090aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      mCurrentMethod.addException(attributes.getValue("type"));
2100aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato    } else if (qName.equals("implements")) {
2110aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      // Resolve interfaces after .xml completely parsed.
2120aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      mApi.mapClassToInterface(mCurrentClass, attributes.getValue("name"));
2130aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato    }
2140aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato  }
2150aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato
2160aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato  @Override
2170aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato  public void endElement(String uri, String localName, String qName) {
2180aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato    if (qName.equals("method")) {
2190aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      mCurrentClass.addMethod((MethodInfo) mCurrentMethod);
2200aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato    } else if (qName.equals("constructor")) {
221040992567205c3b6e4ee01bfb2893bceb915357cJoe Onorato      mCurrentClass.addConstructor((MethodInfo) mCurrentMethod);
2220aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato    } else if (qName.equals("class") || qName.equals("interface")) {
2230aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      mCurrentPackage.addClass(mCurrentClass);
2240aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      mCurrentClass = mClassScope.pop();
2250aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato    } else if (qName.equals("package")) {
2260aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      mApi.addPackage(mCurrentPackage);
2270aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato    }
2280aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato  }
2290aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato
2300aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato  public ApiInfo getApi() {
2310aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato    return mApi;
2320aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato  }
2330aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato
2340aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato  private String qualifiedName(String pkg, String className, ClassInfo parent) {
2350aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato    String parentQName = (parent != null) ? (parent.qualifiedName() + ".") : "";
2360aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato      return pkg + "." + parentQName + className;
2370aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato  }
2380aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato}
2390aff7e0b51a6ad0423bcba8101e17797872a492eJoe Onorato
240