/**
   * Write the XML representation of the API to a file.
   *
   * @param root the RootDoc object passed by Javadoc
   * @return true if no problems encountered
   */
  public static boolean writeXML(RootDoc root) {
    String tempFileName = outputFileName;
    if (outputDirectory != null) {
      tempFileName = outputDirectory;
      if (!tempFileName.endsWith(JDiff.DIR_SEP)) tempFileName += JDiff.DIR_SEP;
      tempFileName += outputFileName;
    }

    try {
      FileOutputStream fos = new FileOutputStream(tempFileName);
      outputFile = new PrintWriter(fos);
      System.out.println("JDiff: writing the API to file '" + tempFileName + "'...");
      if (root.specifiedPackages().length != 0 || root.specifiedClasses().length != 0) {
        RootDocToXML apiWriter = new RootDocToXML();
        apiWriter.emitXMLHeader();
        apiWriter.logOptions();
        apiWriter.processPackages(root);
        apiWriter.emitXMLFooter();
      }
      outputFile.close();
    } catch (IOException e) {
      System.out.println("IO Error while attempting to create " + tempFileName);
      System.out.println("Error: " + e.getMessage());
      System.exit(1);
    }
    // If validation is desired, write out the appropriate api.xsd file
    // in the same directory as the XML file.
    if (XMLToAPI.validateXML) {
      writeXSD();
    }
    return true;
  }
 public static boolean start(RootDoc root) {
   ClassDoc[] classDocs = root.classes();
   if (ArrayUtils.isNotEmpty(classDocs)) {
     for (ClassDoc classDoc : root.classes()) scanClassDoc(result.docs, classDoc);
   }
   return true;
 }
  /**
   * The entry point into the Parser class.
   *
   * @param root A RootDoc intstance obtained via the doclet API
   * @return A XML (XStream) serializable element, containing everything parsed from javadoc doclet
   */
  public static Root ParseRoot(RootDoc root) {
    processingStorage = new HashMap<PackageDoc, ParserMediary>();

    try {
      md5 = MessageDigest.getInstance("MD5");
    } catch (NoSuchAlgorithmException e) {
      log.error("unable to acquire MD5 algorithm", e);
      return null;
    }

    rootXml = new Root();

    ClassDoc[] allClasses = root.classes();

    for (ClassDoc classDoc : allClasses) {
      PackageDoc doc = classDoc.containingPackage();

      ParserMediary mediary = null;

      // the age old 'if I have it pull out existing, if I don't make a new one'
      if (processingStorage.containsKey(doc)) {
        mediary = processingStorage.get(doc);
      } else {
        mediary =
            new ParserMediary(
                doc.name(),
                doc.commentText(),
                ParseAnnotationInstances(doc.annotations(), doc.name()));

        processingStorage.put(doc, mediary);
      }

      if (classDoc.isIncluded()) {
        // dev comment--why do enums show up as ordinary class?
        if (classDoc.isOrdinaryClass() || classDoc.isException() || classDoc.isError()) {
          mediary.addClass(ParseClass(classDoc));
        } else if (classDoc.isEnum()) {
          mediary.addEnum(ParseEnum(classDoc));
        } else if (isAnnotation(classDoc)) {
          mediary.addAnnotation(ParseAnnotation(classDoc));
        } else if (classDoc.isInterface()) {
          mediary.addInterface(ParseInterface(classDoc));
        }
      } else {
        log.debug("Skipping not-included class " + classDoc.qualifiedName());
      }
    }

    if (processingStorage.size() > 0) {
      List list = new ArrayList<Package>();

      for (ParserMediary mediary : processingStorage.values()) {
        list.add(mediary.wrapup());
      }

      rootXml.packages = (Package[]) list.toArray(new Package[] {});
    } else {
      log.warn("No packages found!");
    }

    return rootXml;
  }
Exemple #4
0
 /**
  * Constructor. Build the Tree using the Root of this Javadoc run.
  *
  * @param root Root of the Document.
  * @param configuration The curren configuration of the doclet.
  */
 public ClassTree(RootDoc root, Configuration configuration) {
   buildTree(root.classes(), configuration);
 }
 /**
  * Add at least the first sentence from a doc block for a package to the API. This is used by the
  * report generator if no comment is provided. The default source tree may not include the
  * package.html files, so this may be unavailable in many cases. Need to make sure that HTML tags
  * are not confused with XML tags. This could be done by stuffing the &lt; character to another
  * string or by handling HTML in the parser. This second option is neater. Note that XML expects
  * all element tags to have either a closing "/>" or a matching end element tag. Due to the
  * difficulties of converting incorrect HTML to XHTML, the first option is used.
  */
 public void addPkgDocumentation(RootDoc root, PackageDoc pd, int indent) {
   String rct = null;
   String filename = pd.name();
   try {
     // See if the source path was specified as part of the
     // options and prepend it if it was.
     String srcLocation = null;
     String[][] options = root.options();
     for (int opt = 0; opt < options.length; opt++) {
       if ((options[opt][0]).compareTo("-sourcepath") == 0) {
         srcLocation = options[opt][1];
         break;
       }
     }
     filename = filename.replace('.', JDiff.DIR_SEP.charAt(0));
     if (srcLocation != null) {
       // Make a relative location absolute
       if (srcLocation.startsWith("..")) {
         String curDir = System.getProperty("user.dir");
         while (srcLocation.startsWith("..")) {
           srcLocation = srcLocation.substring(3);
           int idx = curDir.lastIndexOf(JDiff.DIR_SEP);
           curDir = curDir.substring(0, idx + 1);
         }
         srcLocation = curDir + srcLocation;
       }
       filename = srcLocation + JDiff.DIR_SEP + filename;
     }
     // Try both ".htm" and ".html"
     filename += JDiff.DIR_SEP + "package.htm";
     File f2 = new File(filename);
     if (!f2.exists()) {
       filename += "l";
     }
     FileInputStream f = new FileInputStream(filename);
     BufferedReader d = new BufferedReader(new InputStreamReader(f));
     String str = d.readLine();
     // Ignore everything except the lines between <body> elements
     boolean inBody = false;
     while (str != null) {
       if (!inBody) {
         if (str.toLowerCase().trim().startsWith("<body")) {
           inBody = true;
         }
         str = d.readLine(); // Get the next line
         continue; // Ignore the line
       } else {
         if (str.toLowerCase().trim().startsWith("</body")) {
           inBody = false;
           continue; // Ignore the line
         }
       }
       if (rct == null) rct = str + "\n";
       else rct += str + "\n";
       str = d.readLine();
     }
   } catch (java.io.FileNotFoundException e) {
     // If it doesn't exist, that's fine
     if (trace) System.out.println("No package level documentation file at '" + filename + "'");
   } catch (java.io.IOException e) {
     System.out.println("Error reading file \"" + filename + "\": " + e.getMessage());
     System.exit(5);
   }
   if (rct != null) {
     rct = stripNonPrintingChars(rct, (Doc) pd);
     rct = rct.trim();
     if (rct.compareTo("") != 0
         && rct.indexOf(Comments.placeHolderText) == -1
         && rct.indexOf("InsertOtherCommentsHere") == -1) {
       int idx = endOfFirstSentence(rct);
       if (idx == 0) return;
       for (int i = 0; i < indent; i++) outputFile.print(" ");
       outputFile.println("<doc>");
       for (int i = 0; i < indent; i++) outputFile.print(" ");
       String firstSentence = null;
       if (idx == -1) firstSentence = rct;
       else firstSentence = rct.substring(0, idx + 1);
       String firstSentenceNoTags = API.stuffHTMLTags(firstSentence);
       outputFile.println(firstSentenceNoTags);
       for (int i = 0; i < indent; i++) outputFile.print(" ");
       outputFile.println("</doc>");
     }
   }
 }
  /**
   * Process each package and the classes/interfaces within it.
   *
   * @param pd an array of PackageDoc objects
   */
  public void processPackages(RootDoc root) {
    PackageDoc[] specified_pd = root.specifiedPackages();
    Map pdl = new TreeMap();
    for (int i = 0; specified_pd != null && i < specified_pd.length; i++) {
      pdl.put(specified_pd[i].name(), specified_pd[i]);
    }

    // Classes may be specified separately, so merge their packages into the
    // list of specified packages.
    ClassDoc[] cd = root.specifiedClasses();
    // This is lists of the specific classes to document
    Map classesToUse = new HashMap();
    for (int i = 0; cd != null && i < cd.length; i++) {
      PackageDoc cpd = cd[i].containingPackage();
      if (cpd == null && !packagesOnly) {
        // If the RootDoc object has been created from a jar file
        // this duplicates classes, so we have to be able to disable it.
        // TODO this is still null?
        cpd = root.packageNamed("anonymous");
      }
      String pkgName = cpd.name();
      String className = cd[i].name();
      if (trace) System.out.println("Found package " + pkgName + " for class " + className);
      if (!pdl.containsKey(pkgName)) {
        if (trace) System.out.println("Adding new package " + pkgName);
        pdl.put(pkgName, cpd);
      }

      // Keep track of the specific classes to be used for this package
      List classes;
      if (classesToUse.containsKey(pkgName)) {
        classes = (ArrayList) classesToUse.get(pkgName);
      } else {
        classes = new ArrayList();
      }
      classes.add(cd[i]);
      classesToUse.put(pkgName, classes);
    }

    PackageDoc[] pd = (PackageDoc[]) pdl.values().toArray(new PackageDoc[0]);
    for (int i = 0; pd != null && i < pd.length; i++) {
      String pkgName = pd[i].name();

      // Check for an exclude tag in the package doc block, but not
      // in the package.htm[l] file.
      if (!shownElement(pd[i], null)) continue;

      if (trace) System.out.println("PROCESSING PACKAGE: " + pkgName);
      outputFile.println("<package name=\"" + pkgName + "\">");

      int tagCount = pd[i].tags().length;
      if (trace) System.out.println("#tags: " + tagCount);

      List classList;
      if (classesToUse.containsKey(pkgName)) {
        // Use only the specified classes in the package
        System.out.println("Using the specified classes");
        classList = (ArrayList) classesToUse.get(pkgName);
      } else {
        // Use all classes in the package
        classList = new LinkedList(Arrays.asList(pd[i].allClasses()));
      }
      Collections.sort(classList);
      ClassDoc[] classes = new ClassDoc[classList.size()];
      classes = (ClassDoc[]) classList.toArray(classes);
      processClasses(classes, pkgName);

      addPkgDocumentation(root, pd[i], 2);

      outputFile.println("</package>");
    }
  } // processPackages