steveclaflin.comFixJavadocHtml.java |
---|
The javadoc produced by jdk 1.5 produces malformed HTML. Among other problems, there is a mismatched <DL> tag that may cause keyFinder's JavaScript to throw an "Access is denied" error in some Internet Explorer 6 setups. This program traverses the doc directories to fix that specific problem in every class documentation file (it doesn't fix anything else). If keyFinder works for you already, then i wouldn't bother running this.
The following code can be compiled in jdk 1.4 or 1.5. Compile it to a package structure rooted in your jdk's docs/api folder. When it runs, it lists only files that it was not successful in changing. There may be one or two that aren't class pages; that is OK. If you see any failures that are java classes, then that file may not work in keyFinder. (I'm providing source code rather than a compiled file so you can convince yourself that it doesn't do anything malicious I'm assuming that, as a Java programmer, you will know how to compile and run it.)
It took about 4 minutes on my system.
package com.steveclaflin.javadoc.tools;
import java.io.*;
import java.util.regex.*;
import java.util.*;
/**
* Fixes malformed HTML in Javadoc files that prevents keyFinder from
* working properly in Windows/IE5/6 with SP2. Corrects <DL>,
* <DT> and <PRE> tags around the class declaration section.
* Should be run from the docs/api directory of your jdk home.
*/
public class FixJavadocHtml {
/**
* Variables for keeping statistics.
*/
private static int successCount = 0, skipCount = 0, failCount = 0, maxFail = 6;
private static FileFilter isDocFileFilter = new ClassDocFileFilter();
private static Vector vSkip = new Vector();
private static Vector vFail = new Vector();
/**
* Runs the FixJavadocHtml program to process the package roots java, javax
* and org.
*/
public static void main(String[] args) {
System.out.println("FixJavadocHtml " + new File(".").getAbsolutePath());
File[] dirs = new File[] {
new File("java"), new File("javax"), new File("org")
};
for (int i = 0; i < dirs.length; i++) {
fix(dirs[i]);
}
report();
}
/**
* Processes a directory by either fixing entries that are files or
* recursively processing entries that are directories, except directories
* named <i>class-use</i>.
* Replaces <HR>\n<DL>\n<DT><PRE> with
* <HR>\n<PRE>\n<DL>\n<DT>
*
* @param f the directory to process.
*/
public static void fix(File f) {
Pattern searchPattern = Pattern.compile("<DL>\r?\n<DT><PRE>",
Pattern.MULTILINE);
String replaceString = "<PRE>\n<DL>\n<DT>";
if (f.isDirectory()) {
File [] dirs = f.listFiles(isDocFileFilter);
for (int i = 0; i < dirs.length; i++) {
if (!f.getName().equals("class-use")) fix(dirs[i]);
}
}
else if (f.isFile() && f.canRead() && f.canWrite()) {
String name = "";
try {
name = f.getAbsolutePath();
FileInputStream fis = new FileInputStream(f);
int size = fis.available()/2;
InputStreamReader isr = new InputStreamReader(fis);
StringWriter sw = new StringWriter(size);
int c = 0;
while ((c = isr.read()) >= 0) {
sw.write(c);
}
isr.close();
fis.close();
String s = sw.toString();
Matcher m = searchPattern.matcher(s);
if (m.find()) {
s = m.replaceFirst(replaceString);
File temp = new File(name + "X");
f.renameTo(temp);
FileOutputStream fos = new FileOutputStream(name);
OutputStreamWriter osw = new OutputStreamWriter(fos);
osw.write(s);
osw.close();
fos.close();
temp.delete();
successCount++;
}
else {
vSkip.add(name);
skipCount++;
}
} catch (IOException e) {
System.out.println(": FAILED: " + e.getMessage());
e.printStackTrace();
vFail.add(name + e.getMessage());
failCount++;
if (failCount > maxFail) {
report();
System.exit(-1);
}
}
}
}
/**
* Prints a count of files successfully changed, and counts and lists of files skipped and failures.
*/
public static void report() {
System.out.println(successCount + " files changed");
System.out.println();
System.out.println(skipCount + " skipped");
Iterator i = vSkip.iterator();
while (i.hasNext()) {
System.out.println(" " + i.next());
}
System.out.println();
System.out.println(failCount + " failed");
i = vFail.iterator();
while (i.hasNext()) {
System.out.println(" " + i.next());
}
}
/**
* Utility class to allow only files that begin with an uppercase letter and
* end with .html to be processed.
*/
private static class ClassDocFileFilter implements FileFilter {
/**
* Accepts only files that begin with an uppercase letter and
* end with .html.
*
* @return true if the pathname is accepted
*/
public boolean accept(File pathname) {
if (pathname.isDirectory()) return true;
String name = pathname.getName();
return Character.isUpperCase(name.charAt(0)) && name.endsWith(".html");
}
}
}
Return to home page.