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 }