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