1 22 23 package org.xquark.util; 24 25 import java.io.*; 26 import java.io.ByteArrayOutputStream ; 27 import java.io.OutputStream ; 28 import java.io.UnsupportedEncodingException ; 29 30 import org.xml.sax.*; 31 import org.xml.sax.ErrorHandler ; 32 import org.xml.sax.SAXException ; 33 import org.xml.sax.SAXParseException ; 34 import org.xquark.schema.validation.SchemaValidationContext; 35 import org.xquark.schema.validation.ValidatingSchemaHandler; 36 import org.xquark.serialize.XMLSerializer; 37 38 44 public class DocumentCleaner extends ValidatingSchemaHandler 45 { 46 private OutputStream validOutput = null; 48 private OutputStream invalidOutput = null; 49 50 private XMLSerializer serializer = null; 51 private ByteArrayOutputStream buffer = null; 52 53 private byte depth = 0; 54 private SAXParseException lastElementException = null; 55 56 public DocumentCleaner(OutputStream validOutput, OutputStream invalidOutput, 57 SchemaValidationContext context, String encoding) { 58 super(context); 59 this.validOutput = validOutput; 60 this.invalidOutput = invalidOutput; 61 buffer = new ByteArrayOutputStream (); 62 try { 63 serializer = new XMLSerializer(buffer, encoding); 64 } 65 catch (UnsupportedEncodingException e) { 66 } 67 setErrorHandler(new MyErrorHandler()); 68 setContentHandler(serializer); 69 setLexicalHandler(serializer); 70 } 71 72 public DocumentCleaner(OutputStream validOutput, OutputStream invalidOutput) { 73 this(validOutput, invalidOutput, new SchemaValidationContext(), "UTF-8"); 74 } 75 76 public void endDocument() throws SAXException 77 { 78 super.endDocument(); 79 flushBuffer2Both(); 81 try { 82 validOutput.close(); 83 invalidOutput.close(); 84 } 85 catch (IOException e) { 86 throw new SAXException ("Exception when closing streams", e); 87 } 88 } 89 90 private void flushBuffer2Both() throws SAXException 91 { 92 serializer.flush(); 93 try { 94 buffer.writeTo(validOutput); 95 buffer.writeTo(invalidOutput); 96 } 97 catch (IOException e) { 98 throw new SAXException ("Exception when serializing XML prolog", e); 99 } 100 buffer.reset(); 101 } 102 103 public void startElement(String str, String str1, String str2, Attributes attributes) 104 throws SAXException 105 { 106 depth++; 107 switch (depth) 108 { 109 case 1: 110 super.startElement(str, str1, str2, attributes); 111 serializer.completeStartTag(); 112 flushBuffer2Both(); 114 break; 115 116 case 2: 117 lastElementException = null; 118 super.startElement(str, str1, str2, attributes); 119 break; 120 121 default : 122 super.startElement(str, str1, str2, attributes); 123 } 124 } 125 126 public void endElement(String str, String str1, String str2) 127 throws SAXException 128 { 129 super.endElement(str, str1, str2); 130 if (depth== 2){ 131 try { 132 if (lastElementException == null) { 133 serializer.flush(); 134 buffer.writeTo(validOutput); 135 } 136 else { 137 StringBuffer errorMsg = new StringBuffer (); 138 errorMsg.append("\nOriginal location: line "); 139 errorMsg.append(lastElementException.getLineNumber()); 140 errorMsg.append(", column "); 141 errorMsg.append(lastElementException.getColumnNumber()); 142 errorMsg.append('\n'); 143 errorMsg.append(lastElementException.getMessage()); 144 errorMsg.append('\n'); 145 char[] comment = new char[errorMsg.length()]; 146 errorMsg.getChars(0, comment.length, comment, 0); 147 super.comment(comment, 0, comment.length); 148 serializer.flush(); 149 buffer.writeTo(invalidOutput); 150 } 151 buffer.reset(); 152 } 153 catch (IOException e) { 154 throw new SAXException ("Exception when serializing XML prolog", e); 155 } 156 } 157 depth--; 158 } 159 160 private class MyErrorHandler implements ErrorHandler { 161 162 public void error(SAXParseException arg0) throws SAXException { 163 lastElementException = arg0; 164 } 165 166 public void fatalError(SAXParseException arg0) throws SAXException {} 167 public void warning(SAXParseException arg0) throws SAXException {} 168 169 } 170 } 171 | Popular Tags |