1 16 package org.apache.cocoon.xml; 17 18 import java.io.StringWriter ; 19 import java.util.ArrayList ; 20 import java.util.Collection ; 21 import java.util.Enumeration ; 22 import java.util.Iterator ; 23 import java.util.Properties ; 24 25 import javax.xml.transform.OutputKeys ; 26 import javax.xml.transform.TransformerException ; 27 import javax.xml.transform.TransformerFactory ; 28 import javax.xml.transform.sax.SAXTransformerFactory ; 29 import javax.xml.transform.sax.TransformerHandler ; 30 import javax.xml.transform.stream.StreamResult ; 31 32 import org.apache.cocoon.ProcessingException; 33 import org.apache.cocoon.xml.dom.DOMStreamer; 34 import org.w3c.dom.Attr ; 35 import org.w3c.dom.Document ; 36 import org.w3c.dom.Element ; 37 import org.w3c.dom.NamedNodeMap ; 38 import org.w3c.dom.Node ; 39 import org.xml.sax.Attributes ; 40 import org.xml.sax.ContentHandler ; 41 import org.xml.sax.SAXException ; 42 import org.xml.sax.ext.LexicalHandler ; 43 44 52 public class XMLUtils { 53 54 57 public static final Attributes EMPTY_ATTRIBUTES = new ImmutableAttributesImpl(); 58 59 private static final SAXTransformerFactory FACTORY = (SAXTransformerFactory ) TransformerFactory.newInstance(); 60 private static final Properties XML_FORMAT = createDefaultPropertiesForXML(false); 61 private static final Properties XML_FORMAT_NODECL = createDefaultPropertiesForXML(true); 62 63 64 public static void stripDuplicateAttributes(Node node, Node parent) { 68 69 switch(node.getNodeType()) { 71 case Node.DOCUMENT_NODE: { 72 Document doc = (Document )node; 73 Node child = doc.getFirstChild(); 74 while(child != null) { 75 stripDuplicateAttributes(child, node); 76 child = child.getNextSibling(); 77 } 78 break; 79 } 80 81 case Node.ELEMENT_NODE: { 82 Element elt = (Element ) node; 83 NamedNodeMap attrs = elt.getAttributes(); 84 85 ArrayList nodesToRemove = new ArrayList (); 86 int nodesToRemoveNum = 0; 87 88 for(int i = 0; i < attrs.getLength(); i++) { 89 final Node a = attrs.item(i); 90 91 for(int j = 0; j < attrs.getLength(); j++) { 92 final Node b = attrs.item(j); 93 94 if (i != j && (a.getNodeName().equals(b.getNodeName()))) { 96 nodesToRemove.add(b); 97 nodesToRemoveNum++; 98 } 99 } 100 } 101 102 for (int i = 0; i < nodesToRemoveNum; i++) { 103 Attr nodeToDelete = (Attr ) nodesToRemove.get(i); 104 Element nodeToDeleteParent = (Element )node; nodeToDeleteParent.removeAttributeNode(nodeToDelete); 106 } 107 108 nodesToRemove.clear(); 109 110 Node child = elt.getFirstChild(); 111 while(child != null) { 112 stripDuplicateAttributes(child, node); 113 child = child.getNextSibling(); 114 } 115 116 break; 117 } 118 119 default: 120 break; 122 } 123 } 124 125 135 public static XMLConsumer getConsumer(ContentHandler ch, LexicalHandler lh) { 136 if (ch instanceof XMLConsumer) { 137 return (XMLConsumer)ch; 138 } else { 139 if (lh == null && ch instanceof LexicalHandler ) { 140 lh = (LexicalHandler )ch; 141 } 142 return new ContentHandlerWrapper(ch, lh); 143 } 144 } 145 146 154 public static XMLConsumer getConsumer(ContentHandler ch) { 155 return getConsumer(ch, null); 156 } 157 158 163 public static String serializeNodeToXML(Node node) 164 throws ProcessingException { 165 return serializeNode(node, XMLUtils.defaultSerializeToXMLFormat()); 166 } 167 168 178 public static Properties defaultSerializeToXMLFormat() { 179 return defaultSerializeToXMLFormat(false); 180 } 181 182 192 public static Properties defaultSerializeToXMLFormat(boolean omitXMLDeclaration) { 193 final Properties format = createPropertiesForXML(omitXMLDeclaration); 194 format.put(OutputKeys.ENCODING, "ISO-8859-1"); 195 return format; 196 } 197 198 201 private static Properties createDefaultPropertiesForXML(boolean omitXMLDeclaration) { 202 final Properties format = new Properties (); 203 format.put(OutputKeys.METHOD, "xml"); 204 format.put(OutputKeys.OMIT_XML_DECLARATION, (omitXMLDeclaration ? "yes" : "no")); 205 format.put(OutputKeys.INDENT, "yes"); 206 return format; 207 } 208 209 219 public static Properties createPropertiesForXML(boolean omitXMLDeclaration) { 220 224 Properties propertiesForXML = new Properties (omitXMLDeclaration? XML_FORMAT_NODECL: XML_FORMAT); 225 for (Enumeration e = propertiesForXML.propertyNames(); e.hasMoreElements(); ) { 226 String propertyName = (String )e.nextElement(); 227 propertiesForXML.setProperty(propertyName, propertiesForXML.getProperty(propertyName, "")); 228 } 229 return propertiesForXML; 230 } 231 232 238 public static String serializeNode(Node node) 239 throws ProcessingException { 240 return serializeNode(node, XML_FORMAT); 242 } 243 244 251 public static String serializeNode(Node node, Properties format) 252 throws ProcessingException { 253 254 try { 255 if (node == null) { 256 return ""; 257 } 258 259 StringWriter writer = new StringWriter (); 260 TransformerHandler transformerHandler; 261 transformerHandler = FACTORY.newTransformerHandler(); 262 transformerHandler.getTransformer().setOutputProperties(format); 263 transformerHandler.setResult(new StreamResult (writer)); 264 if (node.getNodeType() != Node.DOCUMENT_NODE) { 265 transformerHandler.startDocument(); 266 } 267 DOMStreamer domStreamer = new DOMStreamer(transformerHandler, transformerHandler); 268 domStreamer.stream(node); 269 if (node.getNodeType() != Node.DOCUMENT_NODE) { 270 transformerHandler.endDocument(); 271 } 272 273 return writer.toString(); 274 } catch (TransformerException e) { 275 throw new ProcessingException("TransformerException: " + e, e); 276 } catch (SAXException e) { 277 throw new ProcessingException("SAXException while streaming DOM node to SAX: " + e, e); 278 } 279 } 280 281 288 public static String serialize(org.apache.excalibur.xml.sax.XMLizable xml, Properties format) 289 throws ProcessingException { 290 291 try { 292 if (xml == null) { 293 return ""; 294 } 295 296 StringWriter writer = new StringWriter (); 297 TransformerHandler transformerHandler; 298 transformerHandler = FACTORY.newTransformerHandler(); 299 transformerHandler.getTransformer().setOutputProperties(format); 300 transformerHandler.setResult(new StreamResult (writer)); 301 transformerHandler.startDocument(); 302 xml.toSAX(new EmbeddedXMLPipe(transformerHandler)); 303 transformerHandler.endDocument(); 304 305 return writer.toString(); 306 } catch (TransformerException e) { 307 throw new ProcessingException("TransformerException: " + e, e); 308 } catch (SAXException e) { 309 throw new ProcessingException("SAXException while streaming DOM node to SAX: " + e, e); 310 } 311 } 312 313 319 public static void data(ContentHandler contentHandler, 320 String data) 321 throws SAXException { 322 323 contentHandler.characters(data.toCharArray(), 0, data.length()); 324 } 325 326 333 public static void valueOf(ContentHandler contentHandler, String text) 334 throws SAXException { 335 336 if (text != null) { 337 data(contentHandler, text); 338 } 339 } 340 341 348 public static void valueOf(ContentHandler contentHandler, 349 org.apache.excalibur.xml.sax.XMLizable v) 350 throws SAXException { 351 352 if (v != null) { 353 v.toSAX(contentHandler); 354 } 355 } 356 357 364 public static void valueOf(ContentHandler contentHandler, Node v) 365 throws SAXException { 366 367 if (v != null) { 368 DOMStreamer streamer = new DOMStreamer(contentHandler); 369 if (contentHandler instanceof LexicalHandler ) { 370 streamer.setLexicalHandler((LexicalHandler )contentHandler); 371 } 372 streamer.stream(v); 373 } 374 } 375 376 384 public static void valueOf(ContentHandler contentHandler, 385 Collection v) 386 throws SAXException { 387 388 if (v != null) { 389 Iterator iterator = v.iterator(); 390 while (iterator.hasNext()) { 391 valueOf(contentHandler, iterator.next()); 392 } 393 } 394 } 395 396 407 public static void valueOf(ContentHandler contentHandler, Object v) 408 throws SAXException { 409 410 if (v == null) { 411 return; 412 } 413 414 if (v.getClass().isArray()) { 416 Object [] elements = (Object []) v; 417 418 for (int i = 0; i < elements.length; i++) { 419 valueOf(contentHandler, elements[i]); 420 } 421 return; 422 } 423 424 426 if (v instanceof org.apache.excalibur.xml.sax.XMLizable) { 428 valueOf(contentHandler, (org.apache.excalibur.xml.sax.XMLizable)v); 429 return; 430 } 431 432 if (v instanceof Node ) { 434 valueOf(contentHandler, (Node )v); 435 return; 436 } 437 438 if (v instanceof Collection ) { 440 valueOf(contentHandler, (Collection )v); 441 return; 442 } 443 444 data(contentHandler, String.valueOf(v)); 446 } 447 448 456 public static void createElement(ContentHandler contentHandler, 457 String localName) 458 throws SAXException { 459 460 startElement(contentHandler, localName); 461 endElement(contentHandler, localName); 462 } 463 464 474 public static void createElement(ContentHandler contentHandler, 475 String localName, 476 String stringValue) 477 throws SAXException { 478 479 startElement(contentHandler, localName); 480 data(contentHandler, stringValue); 481 endElement(contentHandler, localName); 482 } 483 484 496 public static void createElement(ContentHandler contentHandler, 497 String localName, 498 Attributes atts) 499 throws SAXException { 500 501 startElement(contentHandler, localName, atts); 502 endElement(contentHandler, localName); 503 } 504 505 519 public static void createElement(ContentHandler contentHandler, 520 String localName, 521 Attributes atts, 522 String stringValue) 523 throws SAXException { 524 525 startElement(contentHandler, localName, atts); 526 data(contentHandler, stringValue); 527 endElement(contentHandler, localName); 528 } 529 530 538 public static void createElementNS(ContentHandler contentHandler, 539 String namespaceURI, 540 String localName) 541 throws SAXException { 542 543 startElement(contentHandler, namespaceURI, localName); 544 endElement(contentHandler, namespaceURI, localName); 545 } 546 547 557 public static void createElementNS(ContentHandler contentHandler, 558 String namespaceURI, 559 String localName, 560 String stringValue) 561 throws SAXException { 562 563 startElement(contentHandler, namespaceURI, localName); 564 data(contentHandler, stringValue); 565 endElement(contentHandler, namespaceURI, localName); 566 } 567 568 580 public static void createElementNS(ContentHandler contentHandler, 581 String namespaceURI, 582 String localName, 583 Attributes atts) 584 throws SAXException { 585 586 startElement(contentHandler, namespaceURI, localName, atts); 587 endElement(contentHandler, namespaceURI, localName); 588 } 589 590 604 public static void createElementNS(ContentHandler contentHandler, 605 String namespaceURI, 606 String localName, 607 Attributes atts, 608 String stringValue) 609 throws SAXException { 610 611 startElement(contentHandler, namespaceURI, localName, atts); 612 data(contentHandler, stringValue); 613 endElement(contentHandler, namespaceURI, localName); 614 } 615 616 617 626 public static void endElement(ContentHandler contentHandler, 627 String localName) 628 throws SAXException { 629 630 contentHandler.endElement("", localName, localName); 631 } 632 633 643 public static void endElement(ContentHandler contentHandler, 644 String namespaceURI, 645 String localName) 646 throws SAXException { 647 648 contentHandler.endElement(namespaceURI, localName, localName); 649 } 650 651 659 public static void startElement(ContentHandler contentHandler, 660 String localName) 661 throws SAXException { 662 663 contentHandler.startElement("", localName, localName, EMPTY_ATTRIBUTES); 664 } 665 666 676 public static void startElement(ContentHandler contentHandler, 677 String namespaceURI, 678 String localName) 679 throws SAXException { 680 681 contentHandler.startElement(namespaceURI, localName, localName, EMPTY_ATTRIBUTES); 682 } 683 684 696 public static void startElement(ContentHandler contentHandler, 697 String localName, 698 Attributes atts) 699 throws SAXException { 700 701 contentHandler.startElement("", localName, localName, atts); 702 } 703 704 718 public static void startElement(ContentHandler contentHandler, 719 String namespaceURI, 720 String localName, 721 Attributes atts) 722 throws SAXException { 723 724 contentHandler.startElement(namespaceURI, localName, localName, atts); 725 } 726 } 727 | Popular Tags |