1 9 package org.ozoneDB.xml.util; 10 11 import org.w3c.dom.*; 12 import org.xml.sax.*; 13 import org.xml.sax.ext.LexicalHandler ; 14 import org.xml.sax.helpers.AttributesImpl ; 15 import org.ozoneDB.util.LogWriter; 16 import org.ozoneDB.util.SimpleLogWriter; 17 18 import java.io.IOException ; 19 import java.io.Serializable ; 20 21 22 30 public final class SAXChunkConsumer implements ContentHandler, LexicalHandler , Serializable { 31 32 private final Node appendTo; 33 34 protected Node startNode = null; 35 36 protected Node currentNode = null; 37 38 protected final Document domFactory; 39 40 protected final boolean domLevel2; 41 42 protected final ContentHandler contentHandler; 43 44 protected final LexicalHandler lexicalHandler; 45 46 protected final ChunkInputStream chunkInput; 47 48 protected final CompiledXMLInputStream cxmlInput; 49 50 protected int processLevel; 51 52 protected ModifiableNodeList resultNodeList; 53 54 private LogWriter logWriter; 55 56 private void init() { 57 logWriter = SimpleLogWriter.getInstance().setDebugLevel(LogWriter.DEBUG); 59 } 60 61 68 public SAXChunkConsumer(Document domFactory, Node appendTo) throws IOException { 69 init(); 70 if (domFactory == null) { 71 throw new IllegalArgumentException ("provided DOM factory node was null!"); 72 } 73 74 this.contentHandler = this; 75 this.lexicalHandler = this; 76 77 this.appendTo = appendTo; 78 this.processLevel = 0; 79 80 this.resultNodeList = new ModifiableNodeList(); 81 82 this.domFactory = domFactory; 83 this.domLevel2 = false; 85 86 this.chunkInput = new ChunkInputStream(null); 87 this.cxmlInput = new CompiledXMLInputStream(this.chunkInput); 88 } 89 90 91 96 public SAXChunkConsumer(ContentHandler contentHandler) throws IOException { 97 init(); 98 if (contentHandler == null) { 99 throw new IllegalArgumentException ("provided SAX content handler was null"); 100 } 101 this.contentHandler = contentHandler; 102 this.lexicalHandler = (contentHandler instanceof LexicalHandler ) 103 ? (LexicalHandler )contentHandler 104 : null; 105 this.appendTo = null; 106 107 this.chunkInput = new ChunkInputStream(null); 108 this.cxmlInput = new CompiledXMLInputStream(this.chunkInput); 109 110 this.domLevel2 = false; 111 this.domFactory = null; 112 } 113 114 115 120 public final void processChunk(byte[] chunkData) throws SAXException, IOException { 121 if (chunkData == null) { 122 throw new IllegalArgumentException ("provided event chunk was null"); 123 } 124 125 this.chunkInput.setBuffer(chunkData); 126 127 while (this.chunkInput.available() > 0) { 128 switch (cxmlInput.readEvent()) { 129 case CXMLContentHandler.START_DOCUMENT: 130 if (logWriter.hasTarget( LogWriter.DEBUG3 )) { 131 logWriter.newEntry(this, "startDocument()", LogWriter.DEBUG3); 132 } 133 this.contentHandler.startDocument(); 134 break; 135 case CXMLContentHandler.END_DOCUMENT: 136 this.contentHandler.endDocument(); 137 return; 138 case CXMLContentHandler.START_PREFIX_MAPPING: 139 this.contentHandler.startPrefixMapping(cxmlInput.readString(), cxmlInput.readString()); 140 break; 141 case CXMLContentHandler.END_PREFIX_MAPPING: 142 this.contentHandler.endPrefixMapping(cxmlInput.readString()); 143 break; 144 case CXMLContentHandler.START_ELEMENT: 145 if (logWriter.hasTarget( LogWriter.DEBUG3 )) { 146 logWriter.newEntry(this, "startElement()", LogWriter.DEBUG3); 147 } 148 int attributes = cxmlInput.readAttributes(); 149 AttributesImpl atts = new AttributesImpl (); 150 for (int i = 0; i < attributes; i++) { 151 atts.addAttribute(cxmlInput.readString(), cxmlInput.readString(), cxmlInput.readString(), 154 cxmlInput.readString(), new String ( cxmlInput.readChars() ) ); 155 } 156 String namespace = cxmlInput.readString(); 157 String localname = cxmlInput.readString(); 158 String qname = cxmlInput.readString(); 159 logWriter.newEntry(this, "namespace=" + namespace + ", localname=" + localname + ", qname=" + qname, LogWriter.DEBUG1); 160 161 this.contentHandler.startElement( namespace, localname, qname , atts); 162 break; 163 case CXMLContentHandler.END_ELEMENT: 164 this.contentHandler.endElement(cxmlInput.readString(), cxmlInput.readString(), cxmlInput.readString()); 165 break; 166 case CXMLContentHandler.CHARACTERS: 167 char[] chars = cxmlInput.readChars(); 168 this.contentHandler.characters(chars, 0, chars.length); 169 break; 170 case CXMLContentHandler.IGNORABLE_WHITESPACE: 171 char[] spaces = cxmlInput.readChars(); 172 this.contentHandler.characters(spaces, 0, spaces.length); 173 break; 174 case CXMLContentHandler.PROCESSING_INSTRUCTION: 175 this.contentHandler.processingInstruction(cxmlInput.readString(), cxmlInput.readString()); 176 break; 177 case CXMLContentHandler.COMMENT: 178 if (this.lexicalHandler != null) { 179 char[] comment = cxmlInput.readChars(); 180 this.lexicalHandler.comment(comment, 0, comment.length); 181 } 182 break; 183 case CXMLContentHandler.START_CDATA: 184 if (this.lexicalHandler != null) { 185 this.lexicalHandler.startCDATA(); 186 } 187 break; 188 case CXMLContentHandler.END_CDATA: 189 if (this.lexicalHandler != null) { 190 this.lexicalHandler.endCDATA(); 191 } 192 break; 193 default: 194 throw new IOException ("parsing error: event not supported: "); 195 } 196 } 197 } 198 199 200 204 public final Node getResultNode() { 205 return startNode; 206 } 207 208 209 213 public final NodeList getResultNodeList() { 214 return resultNodeList; 215 } 216 217 218 222 223 226 public final void startDocument() { 227 if (this.startNode == null) { 228 this.startNode = (this.appendTo != null) ? this.appendTo : this.domFactory; 229 } 230 if (logWriter.hasTarget( LogWriter.DEBUG3 )) { 231 logWriter.newEntry(this, "startDocument()", LogWriter.DEBUG3); 232 } 233 234 if (this.startNode.getNodeType() != Node.DOCUMENT_NODE) { 235 throw new IllegalStateException ("A document can't be appended to another node!"); 236 } 237 238 if (this.startNode.hasChildNodes()) { 239 throw new RuntimeException ("The given DOM document must not have children if a whole document shall be converted!"); 240 } 241 242 if (this.processLevel != 0) { 243 throw new RuntimeException ("startDocument event must not occur within other start-end-event pairs!"); 244 } 245 246 this.resultNodeList.addNode(this.startNode); 247 this.currentNode = this.startNode; 248 this.processLevel++; 249 } 250 251 252 255 public final void endDocument() { 256 if (logWriter.hasTarget( LogWriter.DEBUG3 )) { 257 logWriter.newEntry(this, "endDocument()", LogWriter.DEBUG3); 258 } 259 260 this.currentNode = this.currentNode.getParentNode(); 261 this.processLevel--; 262 } 263 264 265 269 public final void startElement(String _namespaceURI, String _localName, String _rawName, Attributes _atts) { 270 if (logWriter.hasTarget( LogWriter.DEBUG3 )) { 271 logWriter.newEntry(this, "startElement(...)", LogWriter.DEBUG3); 272 } 273 Element newElem; 274 if (domLevel2) { 275 newElem = domFactory.createElementNS(_namespaceURI, _rawName); 276 277 for (int i = 0; i < _atts.getLength(); i++) { 279 newElem.setAttributeNS(_atts.getURI(i), _atts.getQName(i), _atts.getValue(i)); 280 } 281 } else { 282 newElem = domFactory.createElement(_rawName); 283 284 for (int i = 0; i < _atts.getLength(); i++) { 286 newElem.setAttribute(_atts.getQName(i), _atts.getValue(i)); 287 } 288 289 } 290 291 if (this.processLevel == 0) { 292 this.resultNodeList.addNode(newElem); 293 this.startNode = newElem; 294 this.currentNode = newElem; 295 if (this.appendTo != null) { 296 this.appendTo.appendChild(newElem); 297 } 298 } else { 299 this.currentNode.appendChild(newElem); 300 this.currentNode = newElem; 301 } 302 this.processLevel++; 303 } 304 305 306 309 public final void endElement(String _namespaceURI, String _localName, String _rawName) { 310 if (logWriter.hasTarget( LogWriter.DEBUG3 )) { 311 logWriter.newEntry(this, "endElement(...)", LogWriter.DEBUG3); 312 } 313 314 this.currentNode = this.currentNode.getParentNode(); 315 this.processLevel--; 316 } 317 318 319 322 public final void startPrefixMapping(String _prefix, String _uri) { 323 return; 324 } 325 326 327 330 public final void endPrefixMapping(String prefix) { 331 } 333 334 335 338 public final void characters(char[] ch, int start, int length) { 339 340 if ((this.currentNode != null) 341 && (this.currentNode.getNodeType() == Node.CDATA_SECTION_NODE)) { 342 344 StringBuffer chars = new StringBuffer (); 345 346 chars.append(ch, start, length); 347 chars.append(this.currentNode.getNodeValue()); 348 this.currentNode.setNodeValue(chars.toString()); 349 } else { 350 Text textNode = this.domFactory.createTextNode(new String (ch, start, length)); 352 if (logWriter.hasTarget( LogWriter.DEBUG3 )) { 353 logWriter.newEntry(this, "characters(...)", LogWriter.DEBUG3); 354 } 355 356 if (this.processLevel == 0) { 357 this.resultNodeList.addNode(textNode); 358 this.startNode = textNode; 359 this.currentNode = textNode; 360 if (this.appendTo != null) { 361 this.appendTo.appendChild(textNode); 362 } 363 } else { 364 this.currentNode.appendChild(textNode); 365 } 366 } 367 } 368 369 370 373 public final void processingInstruction(String _target, String _data) { 374 ProcessingInstruction piNode = domFactory.createProcessingInstruction(_target, _data); 375 if (logWriter.hasTarget( LogWriter.DEBUG3 )) { 376 logWriter.newEntry(this, "processingInstruction(...)", LogWriter.DEBUG3); 377 } 378 379 if (this.processLevel == 0) { 380 this.resultNodeList.addNode(piNode); 381 this.startNode = piNode; 382 this.currentNode = piNode; 383 if (this.appendTo != null) { 384 this.appendTo.appendChild(piNode); 385 } 386 } else { 387 this.currentNode.appendChild(piNode); 388 } 389 } 390 391 392 395 public final void skippedEntity(java.lang.String _name) { 396 EntityReference erNode = domFactory.createEntityReference(_name); 397 if (logWriter.hasTarget( LogWriter.DEBUG3 )) { 398 logWriter.newEntry(this, "skippedEntity(...)", LogWriter.DEBUG3); 399 } 400 401 if (this.processLevel == 0) { 402 this.resultNodeList.addNode(erNode); 403 this.startNode = erNode; 404 this.currentNode = erNode; 405 if (this.appendTo != null) { 406 this.appendTo.appendChild(erNode); 407 } 408 } else { 409 this.currentNode.appendChild(erNode); 410 } 411 } 412 413 414 417 public final void ignorableWhitespace(char[] _ch, int _start, int _length) { 418 Text whitespace = domFactory.createTextNode(new String (_ch, _start, _length)); 419 if (logWriter.hasTarget( LogWriter.DEBUG3 )) { 420 logWriter.newEntry(this, "ignorableWhitespace(...)", LogWriter.DEBUG3); 421 } 422 423 if (this.processLevel == 0) { 424 this.resultNodeList.addNode(whitespace); 425 this.startNode = whitespace; 426 this.currentNode = whitespace; 427 if (this.appendTo != null) { 428 this.appendTo.appendChild(whitespace); 429 } 430 } else { 431 this.currentNode.appendChild(whitespace); 432 } 433 } 434 435 436 439 public final void setDocumentLocator(Locator locator) { 440 } 442 443 444 448 449 public void comment( char[] ch, int start, int length ) throws SAXException { 450 451 Comment commentNode = this.domFactory.createComment(new String (ch, start, length)); 452 if (logWriter.hasTarget( LogWriter.DEBUG3 )) { 453 logWriter.newEntry(this, "comment(...)", LogWriter.DEBUG3); 454 } 455 456 if (this.processLevel == 0) { 457 this.resultNodeList.addNode(commentNode); 458 this.startNode = commentNode; 459 this.currentNode = commentNode; 460 if (this.appendTo != null) { 461 this.appendTo.appendChild(commentNode); 462 } 463 } else { 464 this.currentNode.appendChild(commentNode); 465 } 466 } 467 468 469 public void startCDATA() throws SAXException { 470 CDATASection cdata = this.domFactory.createCDATASection(""); 471 if (logWriter.hasTarget( LogWriter.DEBUG3 )) { 472 logWriter.newEntry(this, "startCDATA(...)", LogWriter.DEBUG3); 473 } 474 475 if (this.processLevel == 0) { 476 this.resultNodeList.addNode(cdata); 477 this.startNode = cdata; 478 this.currentNode = cdata; 479 if (this.appendTo != null) { 480 this.appendTo.appendChild(cdata); 481 } 482 } else { 483 this.currentNode.appendChild(cdata); 484 this.currentNode = cdata; 485 } 486 this.processLevel++; 487 } 488 489 490 public void endCDATA() throws SAXException { 491 if (logWriter.hasTarget( LogWriter.DEBUG3 )) { 492 logWriter.newEntry(this, "endCDATA(...)", LogWriter.DEBUG3); 493 } 494 495 this.currentNode = this.currentNode.getParentNode(); 496 this.processLevel--; 497 } 498 499 500 public void startDTD(String name, String publicId, String systemId) 501 throws SAXException { 502 } 505 506 507 public void endDTD() throws SAXException { 508 } 511 512 513 public void startEntity(String name) throws SAXException { 514 } 517 518 519 public void endEntity(String name) throws SAXException { 520 } 523 } 524 | Popular Tags |