001 package com.thaiopensource.validate.schematron;
002
003 import org.xml.sax.helpers.DefaultHandler;
004 import org.xml.sax.ErrorHandler;
005 import org.xml.sax.SAXParseException;
006 import org.xml.sax.SAXException;
007 import org.xml.sax.Attributes;
008 import com.thaiopensource.util.Localizer;
009
010 class OutputHandler extends DefaultHandler {
011 private final ErrorHandler eh;
012 private int lineNumber = -1;
013 private int columnNumber = -1;
014 private String systemId = null;
015 private final StringBuffer message = new StringBuffer();
016 private boolean inMessage = false;
017 private final String lineSeparator;
018 private static final String indent = " ";
019 private final Localizer localizer = new Localizer(OutputHandler.class);
020
021 OutputHandler(ErrorHandler eh) {
022 this.eh = eh;
023 this.lineSeparator = System.getProperty("line.separator");
024 }
025
026 public void characters(char ch[], int start, int length)
027 throws SAXException {
028 if (inMessage) {
029 for (int i = 0; i < length; i++) {
030 char c = ch[start + i];
031 switch (c) {
032 case ' ':
033 case '\r':
034 case '\n':
035 case '\t':
036 if (message.length() == 0 || message.charAt(message.length() - 1) != ' ')
037 message.append(' ');
038 break;
039 default:
040 message.append(c);
041 break;
042 }
043 }
044 }
045 }
046
047 public void ignorableWhitespace(char ch[], int start, int length)
048 throws SAXException {
049 characters(ch, start, length);
050 }
051
052 public void startElement(String uri, String localName,
053 String qName, Attributes attributes)
054 throws SAXException {
055 if (localName.equals("failed-assertion")
056 || localName.equals("report")) {
057 String value = attributes.getValue("", "line-number");
058 if (value == null)
059 lineNumber = -1;
060 else {
061 try {
062 lineNumber = Integer.parseInt(value);
063 }
064 catch (NumberFormatException e) {
065 lineNumber = -1;
066 }
067 }
068 value = attributes.getValue("", "column-number");
069 if (value == null)
070 columnNumber = -1;
071 else {
072 try {
073 columnNumber = Integer.parseInt(value);
074 }
075 catch (NumberFormatException e) {
076 columnNumber = -1;
077 }
078 }
079 value = attributes.getValue("", "system-id");
080 if (value != null && value.equals(""))
081 value = null;
082 systemId = value;
083 message.append(localizer.message(localName.equals("failed-assertion")
084 ? "failed_assertion"
085 : "report"));
086 }
087 else if (localName.equals("statement") || localName.equals("diagnostic")) {
088 inMessage = true;
089 message.append(lineSeparator);
090 message.append(indent);
091 }
092 }
093
094 public void endElement(String uri, String localName, String qName)
095 throws SAXException {
096 if (localName.equals("statement") || localName.equals("diagnostic")) {
097 if (message.length() > 0 && message.charAt(message.length() - 1) == ' ')
098 message.setLength(message.length() - 1);
099 inMessage = false;
100 }
101 else if (localName.equals("failed-assertion")
102 || localName.equals("report")) {
103 eh.error(new SAXParseException(message.toString(), null, systemId, lineNumber, columnNumber));
104 message.setLength(0);
105 }
106 }
107 }