import org.xml.sax.*; import java.io.*; import java.net.URL; import java.net.MalformedURLException; /** * This tests an XML parser that has a SAX driver, * by generating the canonical XML for one or more XML files. * This is not written with performance in mind. * * @version $Revision: 1.5 $ $Date: 1998/05/14 01:45:35 $ */ public class XMLTest extends HandlerBase { static public void main(String[] args) { try { if (args.length < 3) { System.err.println("usage: jview XMLTest driver-class output-directory file ..."); System.exit(1); } Class cls = Class.forName(args[0]); File dir = new File(args[1]); if (!dir.isDirectory()) { System.err.println(args[1] + " is not a directory"); System.exit(1); } for (int i = 2; i < args.length; i++) { File file = new File(args[i]); if (file.isAbsolute()) { System.err.println(args[i] + " is not a relative file"); System.exit(1); } Parser parser = (Parser)cls.newInstance(); XMLTest tester = new XMLTest(new File(dir, args[i])); parser.setDocumentHandler(tester); parser.setErrorHandler(tester); try { parser.parse(fileToURL(file).toString()); } catch (SAXParseException e) { tester.out.close(); tester.outFile.delete(); } catch (SAXException e) { System.err.println(args[i] + ": " + e.getMessage()); } } } catch (ClassNotFoundException e) { System.err.println(e.toString()); } catch (InstantiationException e) { System.err.println(e.toString()); } catch (IllegalAccessException e) { System.err.println(e.toString()); } catch (IOException e) { System.err.println(e.toString()); } } static public URL fileToURL(File file) { String path = file.getAbsolutePath(); String fSep = System.getProperty("file.separator"); if (fSep != null && fSep.length() == 1) path = path.replace(fSep.charAt(0), '/'); if (path.length() > 0 && path.charAt(0) != '/') path = '/' + path; try { return new URL("file", null, path); } catch (java.net.MalformedURLException e) { /* According to the spec this could only happen if the file protocol were not recognized. */ throw new Error("unexpected MalformedURLException"); } } private OutputStream out; private File outFile; private StringBuffer buf = new StringBuffer(); private XMLTest(File file) throws IOException { outFile = file; out = new BufferedOutputStream(new FileOutputStream(file)); } public void startElement(String name, AttributeList atts) throws SAXException { try { flushChars(); write("<"); write(name); int len = atts.getLength(); if (len > 0) { int[] v = new int[len]; for (int i = 0; i < len; i++) v[i] = i; /* Do an insertion sort. */ for (int i = 1; i < len; i++) { int n = v[i]; String s = atts.getName(n); int j; for (j = i - 1; j >= 0; j--) { if (s.compareTo(atts.getName(v[j])) >= 0) break; v[j + 1] = v[j]; } v[j + 1] = n; } for (int i = 0; i < len; i++) { write(" "); int n = v[i]; write(atts.getName(n)); write("=\""); String value = atts.getValue(n); int valueLen = value.length(); for (int j = 0; j < valueLen; j++) appendChar(value.charAt(j)); flushChars(); write("\""); } } write(">"); } catch (IOException e) { throw new SAXException(e); } } public void ignorableWhitespace(char[] cbuf, int start, int len) { characters(cbuf, start, len); } public void characters(char[] cbuf, int start, int len) { while (len-- > 0) appendChar(cbuf[start++]); } private void appendChar(char c) { switch (c) { case '&': buf.append("&"); break; case '<': buf.append("<"); break; case '>': buf.append(">"); break; case '"': buf.append("""); break; case '\t': buf.append(" "); break; case '\n': buf.append(" "); break; case '\r': buf.append(" "); break; default: buf.append(c); break; } } public void endElement(String name) throws SAXException { try { flushChars(); write(""); } catch (IOException e) { throw new SAXException(e); } } public void processingInstruction(String target, String data) throws SAXException { try { flushChars(); write(""); } catch (IOException e) { throw new SAXException(e); } } public void startDocument() { } public void endDocument() throws SAXException { try { flushChars(); out.close(); } catch (IOException e) { throw new SAXException(e); } } private void flushChars() throws IOException { if (buf.length() > 0) { write(buf.toString()); buf.setLength(0); } } private void write(String s) throws IOException { int len = s.length(); for (int i = 0; i < len; i++) { char c = s.charAt(i); if (c < 0x80) out.write(c); else { switch (c & 0xF800) { case 0: out.write((((c >> 6) & 0x1F) | 0xC0)); out.write(((c & 0x3F) | 0x80)); break; case 0xD800: char c2; if (i + 1 < len && (c & 0xFC00) == 0xD800 && ((c2 = s.charAt(i + 1)) & 0xFC00) == 0xDC00) { ++i; int n = ((c & 0x3FF) << 10) | (c2 & 0x3FF); n += 0x10000; out.write((((n >> 18) & 0x7) | 0xF0)); out.write((((n >> 12) & 0x3F) | 0x80)); out.write((((n >> 6) & 0x3F) | 0x80)); out.write(((n & 0x3F) | 0x80)); break; } /* this is an error situation really */ /* fall through */ default: out.write((((c >> 12) & 0xF) | 0xE0)); out.write((((c >> 6) & 0x3F) | 0x80)); out.write(((c & 0x3F) | 0x80)); break; } } } } }