1 29 30 package com.caucho.xml.stream; 31 32 import com.caucho.util.L10N; 33 import com.caucho.xml.QDocument; 34 35 import org.w3c.dom.DOMException ; 36 import org.w3c.dom.Document ; 37 import org.w3c.dom.Element ; 38 import org.w3c.dom.Node ; 39 40 import javax.xml.namespace.NamespaceContext ; 41 import javax.xml.stream.XMLStreamException; 42 import javax.xml.stream.XMLStreamWriter; 43 import javax.xml.transform.dom.DOMResult ; 44 import java.util.ArrayList ; 45 import java.util.HashMap ; 46 import java.util.Iterator ; 47 import java.util.List ; 48 import java.util.Map ; 49 import java.util.logging.Logger ; 50 51 public class DOMResultXMLStreamWriterImpl implements XMLStreamWriter { 52 private static final Logger log 53 = Logger.getLogger(DOMResultXMLStreamWriterImpl.class.getName()); 54 private static final L10N L 55 = new L10N(DOMResultXMLStreamWriterImpl.class); 56 57 private DOMResult _result; 58 private Document _document; 59 private Node _current; 60 private boolean _currentIsEmpty = false; 61 62 private SimpleNamespaceContext _context = new SimpleNamespaceContext(null); 63 64 public DOMResultXMLStreamWriterImpl(DOMResult result) 65 throws XMLStreamException 66 { 67 _result = result; 68 69 _current = result.getNode(); 70 71 if (_current == null) { 72 _current = _document = new QDocument(); 73 result.setNode(_document); 74 } 75 else 76 _document = _current.getOwnerDocument(); 77 } 78 79 public void close() 80 throws XMLStreamException 81 { 82 writeEndDocument(); 83 } 84 85 public void flush() 86 throws XMLStreamException 87 { 88 } 89 90 public NamespaceContext getNamespaceContext() 91 { 92 return _context; 93 } 94 95 public String getPrefix(String uri) 96 throws XMLStreamException 97 { 98 return _context.getPrefix(uri); 99 } 100 101 public Object getProperty(String name) 102 throws IllegalArgumentException 103 { 104 throw new PropertyNotSupportedException(name); 105 } 106 107 public void setDefaultNamespace(String uri) 108 throws XMLStreamException 109 { 110 _context.declare("", uri); 111 } 112 113 public void setNamespaceContext(NamespaceContext context) 114 throws XMLStreamException 115 { 116 String message = "please do not set the NamespaceContext"; 117 throw new UnsupportedOperationException (message); 118 } 119 120 public void setPrefix(String prefix, String uri) 121 throws XMLStreamException 122 { 123 _context.declare(prefix, uri); 124 } 125 126 public void writeAttribute(String localName, String value) 127 throws XMLStreamException 128 { 129 try { 130 ((Element ) _current).setAttribute(localName, value); 131 } 132 catch (ClassCastException e) { 133 throw new XMLStreamException(e); 134 } 135 catch (DOMException e) { 136 throw new XMLStreamException(e); 137 } 138 } 139 140 public void writeAttribute(String namespaceURI, String localName, 141 String value) 142 throws XMLStreamException 143 { 144 writeAttribute(_context.declare(namespaceURI), 145 namespaceURI, 146 localName, 147 value); 148 } 149 150 public void writeAttribute(String prefix, String namespaceURI, 151 String localName, String value) 152 throws XMLStreamException 153 { 154 try { 155 _context.declare(prefix, namespaceURI); 156 ((Element ) _current).setAttributeNS(namespaceURI, 157 prefix + ":" + localName, value); 158 } 159 catch (ClassCastException e) { 160 throw new XMLStreamException(e); 161 } 162 catch (DOMException e) { 163 throw new XMLStreamException(e); 164 } 165 } 166 167 public void writeCData(String data) 168 throws XMLStreamException 169 { 170 if (_currentIsEmpty) { 171 popContext(); 172 _currentIsEmpty = false; 173 } 174 175 try { 176 _current.appendChild(_document.createCDATASection(data)); 177 } 178 catch (DOMException e) { 179 throw new XMLStreamException(e); 180 } 181 } 182 183 public void writeCharacters(char[] text, int start, int len) 184 throws XMLStreamException 185 { 186 writeCharacters(new String (text, start, len)); 187 } 188 189 public void writeCharacters(String text) 190 throws XMLStreamException 191 { 192 if (_currentIsEmpty) { 193 popContext(); 194 _currentIsEmpty = false; 195 } 196 197 try { 198 _current.appendChild(_document.createTextNode(text)); 199 } 200 catch (DOMException e) { 201 throw new XMLStreamException(e); 202 } 203 } 204 205 public void writeComment(String data) 206 throws XMLStreamException 207 { 208 if (_currentIsEmpty) { 209 popContext(); 210 _currentIsEmpty = false; 211 } 212 213 try { 214 _current.appendChild(_document.createComment(data)); 215 } 216 catch (DOMException e) { 217 throw new XMLStreamException(e); 218 } 219 } 220 221 public void writeDefaultNamespace(String namespaceURI) 222 throws XMLStreamException 223 { 224 _context.declare("", namespaceURI); 225 } 226 227 public void writeDTD(String dtd) 228 throws XMLStreamException 229 { 230 throw new UnsupportedOperationException (); 231 } 232 233 public void writeEmptyElement(String localName) 234 throws XMLStreamException 235 { 236 if (_currentIsEmpty) 237 popContext(); 238 239 try { 240 Node parent = _current; 241 _current = _document.createElement(localName); 242 parent.appendChild(_current); 243 244 if (! (parent instanceof Document)) 245 pushContext(); 246 247 _currentIsEmpty = true; 248 } 249 catch (DOMException e) { 250 throw new XMLStreamException(e); 251 } 252 } 253 254 public void writeEmptyElement(String namespaceURI, String localName) 255 throws XMLStreamException 256 { 257 writeEmptyElement(_context.declare(namespaceURI), 258 localName, 259 namespaceURI); 260 } 261 262 public void writeEmptyElement(String prefix, String localName, 263 String namespaceURI) 264 throws XMLStreamException 265 { 266 if (_currentIsEmpty) 267 popContext(); 268 269 try { 270 Node parent = _current; 271 _current = _document.createElementNS(namespaceURI, 272 prefix + ":" + localName); 273 parent.appendChild(_current); 274 275 if (! (parent instanceof Document)) 276 pushContext(); 277 278 _currentIsEmpty = true; 279 } 280 catch (DOMException e) { 281 throw new XMLStreamException(e); 282 } 283 } 284 285 public void writeEndDocument() 286 throws XMLStreamException 287 { 288 while (_context != null) 289 popContext(); 290 } 291 292 public void writeEndElement() 293 throws XMLStreamException 294 { 295 try { 296 popContext(); 297 298 if (_currentIsEmpty) 299 popContext(); 300 301 _currentIsEmpty = false; 302 } 303 catch (ClassCastException e) { 304 throw new XMLStreamException(e); 305 } 306 } 307 308 public void writeEntityRef(String name) 309 throws XMLStreamException 310 { 311 if (_currentIsEmpty) { 312 popContext(); 313 _currentIsEmpty = false; 314 } 315 316 try { 317 _current.appendChild(_document.createEntityReference(name)); 318 } 319 catch (DOMException e) { 320 throw new XMLStreamException(e); 321 } 322 } 323 324 public void writeNamespace(String prefix, String namespaceURI) 325 throws XMLStreamException 326 { 327 _context.declare(prefix, namespaceURI); 328 } 329 330 public void writeProcessingInstruction(String target) 331 throws XMLStreamException 332 { 333 writeProcessingInstruction(target, ""); 334 } 335 336 public void writeProcessingInstruction(String target, String data) 337 throws XMLStreamException 338 { 339 if (_currentIsEmpty) { 340 popContext(); 341 _currentIsEmpty = false; 342 } 343 344 try { 345 _current.appendChild(_document.createProcessingInstruction(target, data)); 346 } 347 catch (DOMException e) { 348 throw new XMLStreamException(e); 349 } 350 } 351 352 public void writeStartDocument() 353 throws XMLStreamException 354 { 355 writeStartDocument("1.0"); 356 } 357 358 public void writeStartDocument(String version) 359 throws XMLStreamException 360 { 361 writeStartDocument(version, "utf-8"); 362 } 363 364 public void writeStartDocument(String version, String encoding) 365 throws XMLStreamException 366 { 367 try { 368 _document.setXmlVersion(version); 369 } 371 catch (DOMException e) { 372 throw new XMLStreamException(e); 373 } 374 } 375 376 public void writeStartElement(String localName) 377 throws XMLStreamException 378 { 379 if (_currentIsEmpty) { 380 popContext(); 381 _currentIsEmpty = false; 382 } 383 384 try { 385 Node parent = _current; 386 _current = _document.createElement(localName); 387 parent.appendChild(_current); 388 389 if (! (parent instanceof Document)) 390 pushContext(); 391 392 _currentIsEmpty = false; 393 } 394 catch (DOMException e) { 395 throw new XMLStreamException(e); 396 } 397 } 398 399 public void writeStartElement(String namespaceURI, String localName) 400 throws XMLStreamException 401 { 402 writeStartElement(_context.declare(namespaceURI), 403 localName, 404 namespaceURI); 405 } 406 407 public void writeStartElement(String prefix, String localName, 408 String namespaceURI) 409 throws XMLStreamException 410 { 411 if (_currentIsEmpty) { 412 popContext(); 413 _currentIsEmpty = false; 414 } 415 416 try { 417 Node parent = _current; 418 _current = _document.createElementNS(namespaceURI, 419 prefix + ":" + localName); 420 parent.appendChild(_current); 421 422 if (! (parent instanceof Document)) 423 pushContext(); 424 425 _currentIsEmpty = false; 426 } 427 catch (DOMException e) { 428 throw new XMLStreamException(e); 429 } 430 } 431 432 434 private void pushContext() 435 { 436 _context = new SimpleNamespaceContext(_context); 437 } 438 439 private void popContext() 440 { 441 if (_current instanceof Element ) { 442 Element element = (Element ) _current; 443 444 for (Map.Entry <String ,String > entry : 445 _context.getPrefixMap().entrySet()) { 446 447 if ("".equals(entry.getKey())) 448 element.setAttribute("xmlns", entry.getValue()); 449 else 450 element.setAttributeNS("http://www.w3.org/2000/xmlns/", 451 "xmlns:" + entry.getKey(), 452 entry.getValue()); 453 } 454 } 455 456 if (_context != null) 457 _context = _context.getParent(); 458 459 _current = _current.getParentNode(); 460 } 461 462 private static class SimpleNamespaceContext implements NamespaceContext { 463 private HashMap <String ,String > _uris = new HashMap <String ,String >(); 464 private HashMap <String ,List <String >> _prefixes 465 = new HashMap <String ,List <String >>(); 466 private SimpleNamespaceContext _parent; 467 private int _prefixCounter = 0; 468 469 public SimpleNamespaceContext(SimpleNamespaceContext parent) 470 { 471 _parent = parent; 472 } 473 474 public String getNamespaceURI(String prefix) 475 { 476 return _uris.get(prefix); 477 } 478 479 public String getPrefix(String namespaceURI) 480 { 481 List <String > prefixes = _prefixes.get(namespaceURI); 482 483 if (prefixes == null || prefixes.size() == 0) 484 return null; 485 486 return prefixes.get(0); 487 } 488 489 public Iterator getPrefixes(String namespaceURI) 490 { 491 List <String > prefixes = _prefixes.get(namespaceURI); 492 493 if (prefixes == null) { 494 prefixes = new ArrayList <String >(); 495 _prefixes.put(namespaceURI, prefixes); 496 } 497 498 return prefixes.iterator(); 499 } 500 501 public HashMap <String ,String > getPrefixMap() 502 { 503 return _uris; 504 } 505 506 public String declare(String namespaceURI) 507 { 508 String prefix = "ns" + _prefixCounter; 509 declare(prefix, namespaceURI); 510 _prefixCounter++; 511 512 return prefix; 513 } 514 515 public void declare(String prefix, String namespaceURI) 516 { 517 _uris.put(prefix, namespaceURI); 518 519 List <String > prefixes = _prefixes.get(namespaceURI); 520 521 if (prefixes == null) { 522 prefixes = new ArrayList <String >(); 523 _prefixes.put(namespaceURI, prefixes); 524 } 525 526 prefixes.add(prefix); 527 } 528 529 public SimpleNamespaceContext getParent() 530 { 531 return _parent; 532 } 533 } 534 } 535 | Popular Tags |