1 17 18 19 20 package org.apache.fop.util; 21 22 import java.util.List ; 23 import java.util.Map ; 24 import java.util.Stack ; 25 26 import org.w3c.dom.Document ; 27 import org.w3c.dom.NamedNodeMap ; 28 import org.w3c.dom.Node ; 29 30 import org.xml.sax.ContentHandler ; 31 import org.xml.sax.SAXException ; 32 import org.xml.sax.ext.LexicalHandler ; 33 import org.xml.sax.helpers.AttributesImpl ; 34 35 41 public class DOM2SAX { 42 43 private static final String EMPTYSTRING = ""; 44 private static final String XMLNS_PREFIX = "xmlns"; 45 46 private ContentHandler contentHandler; 47 private LexicalHandler lexicalHandler; 48 49 private Map prefixes = new java.util.HashMap (); 50 51 55 public DOM2SAX(ContentHandler handler) { 56 this.contentHandler = handler; 57 if (handler instanceof LexicalHandler ) { 58 this.lexicalHandler = (LexicalHandler )handler; 59 } 60 } 61 62 68 public void writeDocument(Document doc, boolean fragment) throws SAXException { 69 if (!fragment) { 70 contentHandler.startDocument(); 71 } 72 for (Node n = doc.getFirstChild(); n != null; 73 n = n.getNextSibling()) { 74 writeNode(n); 75 } 76 if (!fragment) { 77 contentHandler.endDocument(); 78 } 79 } 80 81 85 private boolean startPrefixMapping(String prefix, String uri) 86 throws SAXException { 87 boolean pushed = true; 88 Stack uriStack = (Stack )prefixes.get(prefix); 89 90 if (uriStack != null) { 91 if (uriStack.isEmpty()) { 92 contentHandler.startPrefixMapping(prefix, uri); 93 uriStack.push(uri); 94 } else { 95 final String lastUri = (String ) uriStack.peek(); 96 if (!lastUri.equals(uri)) { 97 contentHandler.startPrefixMapping(prefix, uri); 98 uriStack.push(uri); 99 } else { 100 pushed = false; 101 } 102 } 103 } else { 104 contentHandler.startPrefixMapping(prefix, uri); 105 uriStack = new Stack (); 106 prefixes.put(prefix, uriStack); 107 uriStack.push(uri); 108 } 109 return pushed; 110 } 111 112 116 private void endPrefixMapping(String prefix) throws SAXException { 117 final Stack uriStack = (Stack )prefixes.get(prefix); 118 119 if (uriStack != null) { 120 contentHandler.endPrefixMapping(prefix); 121 uriStack.pop(); 122 } 123 } 124 125 130 private static String getLocalName(Node node) { 131 final String localName = node.getLocalName(); 132 133 if (localName == null) { 134 final String qname = node.getNodeName(); 135 final int col = qname.lastIndexOf(':'); 136 return (col > 0) ? qname.substring(col + 1) : qname; 137 } 138 return localName; 139 } 140 141 146 private void writeNode(Node node) 147 throws SAXException { 148 if (node == null) { 149 return; 150 } 151 152 switch (node.getNodeType()) { 153 case Node.ATTRIBUTE_NODE: case Node.DOCUMENT_FRAGMENT_NODE: 155 case Node.DOCUMENT_TYPE_NODE: 156 case Node.ENTITY_NODE: 157 case Node.ENTITY_REFERENCE_NODE: 158 case Node.NOTATION_NODE: 159 break; 161 case Node.CDATA_SECTION_NODE: 162 final String cdata = node.getNodeValue(); 163 if (lexicalHandler != null) { 164 lexicalHandler.startCDATA(); 165 contentHandler.characters(cdata.toCharArray(), 0, cdata.length()); 166 lexicalHandler.endCDATA(); 167 } else { 168 contentHandler.characters(cdata.toCharArray(), 0, cdata.length()); 171 } 172 break; 173 174 case Node.COMMENT_NODE: if (lexicalHandler != null) { 176 final String value = node.getNodeValue(); 177 lexicalHandler.comment(value.toCharArray(), 0, value.length()); 178 } 179 break; 180 case Node.DOCUMENT_NODE: 181 contentHandler.startDocument(); 182 Node next = node.getFirstChild(); 183 while (next != null) { 184 writeNode(next); 185 next = next.getNextSibling(); 186 } 187 contentHandler.endDocument(); 188 break; 189 190 case Node.ELEMENT_NODE: 191 String prefix; 192 List pushedPrefixes = new java.util.ArrayList (); 193 final AttributesImpl attrs = new AttributesImpl (); 194 final NamedNodeMap map = node.getAttributes(); 195 final int length = map.getLength(); 196 197 for (int i = 0; i < length; i++) { 199 final Node attr = map.item(i); 200 final String qnameAttr = attr.getNodeName(); 201 202 if (qnameAttr.startsWith(XMLNS_PREFIX)) { 204 final String uriAttr = attr.getNodeValue(); 205 final int colon = qnameAttr.lastIndexOf(':'); 206 prefix = (colon > 0) ? qnameAttr.substring(colon + 1) 207 : EMPTYSTRING; 208 if (startPrefixMapping(prefix, uriAttr)) { 209 pushedPrefixes.add(prefix); 210 } 211 } 212 } 213 214 for (int i = 0; i < length; i++) { 216 final Node attr = map.item(i); 217 final String qnameAttr = attr.getNodeName(); 218 219 if (!qnameAttr.startsWith(XMLNS_PREFIX)) { 221 final String uriAttr = attr.getNamespaceURI(); 222 223 if (uriAttr != null) { 225 final int colon = qnameAttr.lastIndexOf(':'); 226 prefix = (colon > 0) ? qnameAttr.substring(0, colon) 227 : EMPTYSTRING; 228 if (startPrefixMapping(prefix, uriAttr)) { 229 pushedPrefixes.add(prefix); 230 } 231 } 232 233 attrs.addAttribute(attr.getNamespaceURI(), 235 getLocalName(attr), qnameAttr, "CDATA", attr 236 .getNodeValue()); 237 } 238 } 239 240 final String qname = node.getNodeName(); 242 final String uri = node.getNamespaceURI(); 243 final String localName = getLocalName(node); 244 245 if (uri != null) { 247 final int colon = qname.lastIndexOf(':'); 248 prefix = (colon > 0) ? qname.substring(0, colon) : EMPTYSTRING; 249 if (startPrefixMapping(prefix, uri)) { 250 pushedPrefixes.add(prefix); 251 } 252 } 253 254 contentHandler.startElement(uri, localName, qname, attrs); 256 257 next = node.getFirstChild(); 259 while (next != null) { 260 writeNode(next); 261 next = next.getNextSibling(); 262 } 263 264 contentHandler.endElement(uri, localName, qname); 266 267 final int nPushedPrefixes = pushedPrefixes.size(); 269 for (int i = 0; i < nPushedPrefixes; i++) { 270 endPrefixMapping((String )pushedPrefixes.get(i)); 271 } 272 break; 273 274 case Node.PROCESSING_INSTRUCTION_NODE: 275 contentHandler.processingInstruction(node.getNodeName(), node.getNodeValue()); 276 break; 277 278 case Node.TEXT_NODE: 279 final String data = node.getNodeValue(); 280 contentHandler.characters(data.toCharArray(), 0, data.length()); 281 break; 282 default: 283 } 285 } 286 287 288 } 289 | Popular Tags |