/** * 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; }
/** * 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 < 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>"); } } }
/** Write the XML Schema file used for validation. */ public static void writeXSD() { String xsdFileName = outputFileName; if (outputDirectory == null) { int idx = xsdFileName.lastIndexOf('\\'); int idx2 = xsdFileName.lastIndexOf('/'); if (idx == -1 && idx2 == -1) { xsdFileName = ""; } else if (idx == -1 && idx2 != -1) { xsdFileName = xsdFileName.substring(0, idx2); } else if (idx != -1 && idx2 == -1) { xsdFileName = xsdFileName.substring(0, idx); } else if (idx != -1 && idx2 != -1) { int max = idx2 > idx ? idx2 : idx; xsdFileName = xsdFileName.substring(0, max); } } else { xsdFileName = outputDirectory; if (!xsdFileName.endsWith(JDiff.DIR_SEP)) xsdFileName += JDiff.DIR_SEP; } xsdFileName += "api.xsd"; try { FileOutputStream fos = new FileOutputStream(xsdFileName); PrintWriter xsdFile = new PrintWriter(fos); // The contents of the api.xsd file xsdFile.println("<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"no\"?>"); xsdFile.println("<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">"); xsdFile.println(""); xsdFile.println("<xsd:annotation>"); xsdFile.println(" <xsd:documentation>"); xsdFile.println(" Schema for JDiff API representation."); xsdFile.println(" </xsd:documentation>"); xsdFile.println("</xsd:annotation>"); xsdFile.println(); xsdFile.println("<xsd:element name=\"api\" type=\"apiType\"/>"); xsdFile.println(""); xsdFile.println("<xsd:complexType name=\"apiType\">"); xsdFile.println(" <xsd:sequence>"); xsdFile.println( " <xsd:element name=\"package\" type=\"packageType\" minOccurs='1' maxOccurs='unbounded'/>"); xsdFile.println(" </xsd:sequence>"); xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>"); xsdFile.println(" <xsd:attribute name=\"jdversion\" type=\"xsd:string\"/>"); xsdFile.println("</xsd:complexType>"); xsdFile.println(); xsdFile.println("<xsd:complexType name=\"packageType\">"); xsdFile.println(" <xsd:sequence>"); xsdFile.println(" <xsd:choice maxOccurs='unbounded'>"); xsdFile.println(" <xsd:element name=\"class\" type=\"classType\"/>"); xsdFile.println(" <xsd:element name=\"interface\" type=\"classType\"/>"); xsdFile.println(" </xsd:choice>"); xsdFile.println( " <xsd:element name=\"doc\" type=\"xsd:string\" minOccurs='0' maxOccurs='1'/>"); xsdFile.println(" </xsd:sequence>"); xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>"); xsdFile.println("</xsd:complexType>"); xsdFile.println(); xsdFile.println("<xsd:complexType name=\"classType\">"); xsdFile.println(" <xsd:sequence>"); xsdFile.println( " <xsd:element name=\"implements\" type=\"interfaceTypeName\" minOccurs='0' maxOccurs='unbounded'/>"); xsdFile.println( " <xsd:element name=\"constructor\" type=\"constructorType\" minOccurs='0' maxOccurs='unbounded'/>"); xsdFile.println( " <xsd:element name=\"method\" type=\"methodType\" minOccurs='0' maxOccurs='unbounded'/>"); xsdFile.println( " <xsd:element name=\"field\" type=\"fieldType\" minOccurs='0' maxOccurs='unbounded'/>"); xsdFile.println( " <xsd:element name=\"doc\" type=\"xsd:string\" minOccurs='0' maxOccurs='1'/>"); xsdFile.println(" </xsd:sequence>"); xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>"); xsdFile.println(" <xsd:attribute name=\"extends\" type=\"xsd:string\" use='optional'/>"); xsdFile.println(" <xsd:attribute name=\"abstract\" type=\"xsd:boolean\"/>"); xsdFile.println(" <xsd:attribute name=\"src\" type=\"xsd:string\" use='optional'/>"); xsdFile.println(" <xsd:attribute name=\"static\" type=\"xsd:boolean\"/>"); xsdFile.println(" <xsd:attribute name=\"final\" type=\"xsd:boolean\"/>"); xsdFile.println(" <xsd:attribute name=\"deprecated\" type=\"xsd:string\"/>"); xsdFile.println(" <xsd:attribute name=\"visibility\" type=\"xsd:string\"/>"); xsdFile.println("</xsd:complexType>"); xsdFile.println(); xsdFile.println("<xsd:complexType name=\"interfaceTypeName\">"); xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>"); xsdFile.println("</xsd:complexType>"); xsdFile.println(); xsdFile.println("<xsd:complexType name=\"constructorType\">"); xsdFile.println(" <xsd:sequence>"); xsdFile.println( " <xsd:element name=\"exception\" type=\"exceptionType\" minOccurs='0' maxOccurs='unbounded'/>"); xsdFile.println( " <xsd:element name=\"doc\" type=\"xsd:string\" minOccurs='0' maxOccurs='1'/>"); xsdFile.println(" </xsd:sequence>"); xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>"); xsdFile.println(" <xsd:attribute name=\"type\" type=\"xsd:string\" use='optional'/>"); xsdFile.println(" <xsd:attribute name=\"src\" type=\"xsd:string\" use='optional'/>"); xsdFile.println(" <xsd:attribute name=\"static\" type=\"xsd:boolean\"/>"); xsdFile.println(" <xsd:attribute name=\"final\" type=\"xsd:boolean\"/>"); xsdFile.println(" <xsd:attribute name=\"deprecated\" type=\"xsd:string\"/>"); xsdFile.println(" <xsd:attribute name=\"visibility\" type=\"xsd:string\"/>"); xsdFile.println("</xsd:complexType>"); xsdFile.println(); xsdFile.println("<xsd:complexType name=\"paramsType\">"); xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>"); xsdFile.println(" <xsd:attribute name=\"type\" type=\"xsd:string\"/>"); xsdFile.println("</xsd:complexType>"); xsdFile.println(); xsdFile.println("<xsd:complexType name=\"exceptionType\">"); xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>"); xsdFile.println(" <xsd:attribute name=\"type\" type=\"xsd:string\"/>"); xsdFile.println("</xsd:complexType>"); xsdFile.println(); xsdFile.println("<xsd:complexType name=\"methodType\">"); xsdFile.println(" <xsd:sequence>"); xsdFile.println( " <xsd:element name=\"param\" type=\"paramsType\" minOccurs='0' maxOccurs='unbounded'/>"); xsdFile.println( " <xsd:element name=\"exception\" type=\"exceptionType\" minOccurs='0' maxOccurs='unbounded'/>"); xsdFile.println( " <xsd:element name=\"doc\" type=\"xsd:string\" minOccurs='0' maxOccurs='1'/>"); xsdFile.println(" </xsd:sequence>"); xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>"); xsdFile.println(" <xsd:attribute name=\"return\" type=\"xsd:string\" use='optional'/>"); xsdFile.println(" <xsd:attribute name=\"abstract\" type=\"xsd:boolean\"/>"); xsdFile.println(" <xsd:attribute name=\"native\" type=\"xsd:boolean\"/>"); xsdFile.println(" <xsd:attribute name=\"synchronized\" type=\"xsd:boolean\"/>"); xsdFile.println(" <xsd:attribute name=\"src\" type=\"xsd:string\" use='optional'/>"); xsdFile.println(" <xsd:attribute name=\"static\" type=\"xsd:boolean\"/>"); xsdFile.println(" <xsd:attribute name=\"final\" type=\"xsd:boolean\"/>"); xsdFile.println(" <xsd:attribute name=\"deprecated\" type=\"xsd:string\"/>"); xsdFile.println(" <xsd:attribute name=\"visibility\" type=\"xsd:string\"/>"); xsdFile.println("</xsd:complexType>"); xsdFile.println(); xsdFile.println("<xsd:complexType name=\"fieldType\">"); xsdFile.println(" <xsd:sequence>"); xsdFile.println( " <xsd:element name=\"doc\" type=\"xsd:string\" minOccurs='0' maxOccurs='1'/>"); xsdFile.println(" </xsd:sequence>"); xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>"); xsdFile.println(" <xsd:attribute name=\"type\" type=\"xsd:string\"/>"); xsdFile.println(" <xsd:attribute name=\"transient\" type=\"xsd:boolean\"/>"); xsdFile.println(" <xsd:attribute name=\"volatile\" type=\"xsd:boolean\"/>"); xsdFile.println(" <xsd:attribute name=\"value\" type=\"xsd:string\" use='optional'/>"); xsdFile.println(" <xsd:attribute name=\"src\" type=\"xsd:string\" use='optional'/>"); xsdFile.println(" <xsd:attribute name=\"static\" type=\"xsd:boolean\"/>"); xsdFile.println(" <xsd:attribute name=\"final\" type=\"xsd:boolean\"/>"); xsdFile.println(" <xsd:attribute name=\"deprecated\" type=\"xsd:string\"/>"); xsdFile.println(" <xsd:attribute name=\"visibility\" type=\"xsd:string\"/>"); xsdFile.println("</xsd:complexType>"); xsdFile.println(); xsdFile.println("</xsd:schema>"); xsdFile.close(); } catch (IOException e) { System.out.println("IO Error while attempting to create " + xsdFileName); System.out.println("Error: " + e.getMessage()); System.exit(1); } }