1 17 package org.eclipse.emf.ecore.xmi.impl; 18 19 20 import java.io.BufferedInputStream ; 21 import java.io.IOException ; 22 import java.io.InputStream ; 23 import java.util.Collections ; 24 import java.util.Iterator ; 25 import java.util.Map ; 26 27 import javax.xml.parsers.ParserConfigurationException ; 28 import javax.xml.parsers.SAXParser ; 29 import javax.xml.parsers.SAXParserFactory ; 30 31 import org.w3c.dom.CDATASection ; 32 import org.w3c.dom.Comment ; 33 import org.w3c.dom.Document ; 34 import org.w3c.dom.DocumentType ; 35 import org.w3c.dom.Element ; 36 import org.w3c.dom.NamedNodeMap ; 37 import org.w3c.dom.Node ; 38 import org.xml.sax.Attributes ; 39 import org.xml.sax.InputSource ; 40 import org.xml.sax.SAXException ; 41 import org.xml.sax.ext.LexicalHandler ; 42 import org.xml.sax.helpers.AttributesImpl ; 43 import org.xml.sax.helpers.DefaultHandler ; 44 45 import org.eclipse.emf.ecore.resource.Resource; 46 import org.eclipse.emf.ecore.util.ExtendedMetaData; 47 import org.eclipse.emf.ecore.xmi.XMIException; 48 import org.eclipse.emf.ecore.xmi.XMLHelper; 49 import org.eclipse.emf.ecore.xmi.XMLLoad; 50 import org.eclipse.emf.ecore.xmi.XMLParserPool; 51 import org.eclipse.emf.ecore.xmi.XMLResource; 52 53 54 58 public class XMLLoadImpl implements XMLLoad 59 { 60 protected static final String SAX_LEXICAL_PROPERTY = "http://xml.org/sax/properties/lexical-handler"; 61 protected static final int BUFFER_SIZE = 200; 62 protected XMLResource resource; 63 protected InputStream is; 64 protected XMLHelper helper; 65 protected Map options; 66 67 public XMLLoadImpl(XMLHelper helper) 68 { 69 this.helper = helper; 70 } 71 72 76 public void load(XMLResource resource, InputStream inputStream, Map options) throws IOException 77 { 78 this.resource = resource; 79 is = inputStream; 80 this.options = options; 81 XMLParserPool pool = (XMLParserPool)options.get(XMLResource.OPTION_USE_PARSER_POOL); 82 Map parserFeatures = (Map ) options.get(XMLResource.OPTION_PARSER_FEATURES); 83 Map parserProperties = (Map )options.get(XMLResource.OPTION_PARSER_PROPERTIES); 84 parserFeatures = (parserFeatures == null) ? Collections.EMPTY_MAP : parserFeatures; 85 parserProperties = (parserProperties == null) ? Collections.EMPTY_MAP : parserProperties; 86 87 String encoding = getEncoding(); 89 resource.setEncoding(encoding); 90 try 91 { 92 SAXParser parser; 93 94 if (pool != null) 95 { 96 parser = pool.get(parserFeatures, parserProperties, Boolean.TRUE.equals(options.get(XMLResource.OPTION_USE_LEXICAL_HANDLER))); 98 } 99 else 100 { 101 parser = makeParser(); 102 if (parserFeatures != null) 104 { 105 for (Iterator i = parserFeatures.keySet().iterator(); i.hasNext();) 106 { 107 String feature = (String ) i.next(); 108 parser.getXMLReader().setFeature(feature, ((Boolean ) parserFeatures.get(feature)).booleanValue()); 109 } 110 } 111 if (parserProperties !=null) 112 { 113 for (Iterator i = parserProperties.keySet().iterator(); i.hasNext();) 114 { 115 String property = (String ) i.next(); 116 parser.getXMLReader().setProperty(property, parserProperties.get(property)); 117 } 118 } 119 } 120 121 InputSource inputSource = new InputSource (is); 122 if (resource.getURI() != null) 123 { 124 String resourceURI = resource.getURI().toString(); 125 inputSource.setPublicId(resourceURI); 126 inputSource.setSystemId(resourceURI); 127 } 128 129 DefaultHandler defaultHandler = makeDefaultHandler(); 130 131 if (options != null && Boolean.TRUE.equals(options.get(XMLResource.OPTION_USE_LEXICAL_HANDLER))) 133 { 134 if (parserProperties == null || parserProperties.get(SAX_LEXICAL_PROPERTY) == null) 135 { 136 parser.setProperty(SAX_LEXICAL_PROPERTY, defaultHandler); 137 } 138 } 139 140 parser.parse(inputSource, defaultHandler); 141 142 if (defaultHandler instanceof SAXWrapper) 144 { 145 ((SAXWrapper)defaultHandler).handler = null; 146 } 147 148 if (pool != null) 150 { 151 pool.release(parser, parserFeatures, parserProperties, Boolean.TRUE.equals(options.get(XMLResource.OPTION_USE_LEXICAL_HANDLER))); 152 } 153 154 helper = null; 155 if (!resource.getErrors().isEmpty()) 156 { 157 Exception error = (Exception )resource.getErrors().get(0); 158 if (error instanceof XMIException) 159 { 160 XMIException exception = (XMIException)error; 161 if (exception.getWrappedException() != null) 162 { 163 throw new Resource.IOWrappedException(exception.getWrappedException()); 164 } 165 } 166 throw new Resource.IOWrappedException(error); 167 } 168 } 169 catch (SAXException exception) 170 { 171 if (exception.getException() != null) 172 { 173 throw new Resource.IOWrappedException(exception.getException()); 174 } 175 else 176 { 177 throw new Resource.IOWrappedException(exception); 178 } 179 } 180 catch (ParserConfigurationException exception) 181 { 182 throw new Resource.IOWrappedException(exception); 183 } 184 } 185 186 190 protected SAXParser makeParser() throws ParserConfigurationException , SAXException 191 { 192 SAXParserFactory f = SAXParserFactory.newInstance(); 193 return f.newSAXParser(); 194 } 195 196 protected DefaultHandler makeDefaultHandler() 197 { 198 return new SAXWrapper(new SAXXMLHandler(resource, helper, options)); 199 } 200 201 protected String getEncoding() throws IOException 202 { 203 if (!is.markSupported()) 204 is = new BufferedInputStream (is); 205 206 byte[] buffer = readBuffer(); 207 return XMLHandler.getXMLEncoding(buffer); 208 } 209 210 protected byte[] readBuffer() throws IOException 211 { 212 if (is.available() == 0) 213 { 214 return new byte[0]; 215 } 216 217 byte[] buffer = new byte[BUFFER_SIZE]; 218 is.mark(BUFFER_SIZE); 219 int bytesRead = is.read(buffer, 0, BUFFER_SIZE); 220 int totalBytesRead = bytesRead; 221 222 while (bytesRead != -1 && (totalBytesRead < BUFFER_SIZE)) 223 { 224 bytesRead = is.read(buffer, totalBytesRead, BUFFER_SIZE - totalBytesRead); 225 226 if (bytesRead != -1) 227 totalBytesRead += bytesRead; 228 } 229 230 if (totalBytesRead < BUFFER_SIZE) 231 { 232 byte[] smallerBuffer = new byte[totalBytesRead]; 233 System.arraycopy(buffer, 0, smallerBuffer, 0, totalBytesRead); 234 smallerBuffer = buffer; 235 } 236 237 is.reset(); 238 return buffer; 239 } 240 241 244 public void load(XMLResource resource, Node node, Map options) throws IOException 245 { 246 this.resource = resource; 247 this.options = options; 248 DefaultHandler handler = makeDefaultHandler(); 249 LexicalHandler lexicalHandler = null; 250 251 if (options != null && Boolean.TRUE.equals(options.get(XMLResource.OPTION_USE_LEXICAL_HANDLER))) 252 { 253 lexicalHandler = (LexicalHandler )handler; 254 } 255 256 AttributesProxy attributesProxy = new AttributesProxy(); 257 try 258 { 259 short type = node.getNodeType(); 260 if (type == Node.ELEMENT_NODE) 261 { 262 handler.startDocument(); 263 if (options != null && Boolean.TRUE.equals(options.get(XMLResource.OPTION_DOM_USE_NAMESPACES_IN_SCOPE))) 264 { 265 traverseElement((Element )node, attributesProxy, handler, lexicalHandler); 266 } 267 else 268 { 269 traverse(node, attributesProxy, handler, lexicalHandler); 270 } 271 handler.endDocument(); 272 } 273 else 274 { 275 traverse(node, attributesProxy, handler, lexicalHandler); 276 } 277 } 278 catch (SAXException e) 279 { 280 } 282 283 if (!resource.getErrors().isEmpty()) 284 { 285 Exception error = (Exception )resource.getErrors().get(0); 286 if (error instanceof XMIException) 287 { 288 XMIException exception = (XMIException)error; 289 if (exception.getWrappedException() != null) 290 { 291 throw new Resource.IOWrappedException(exception.getWrappedException()); 292 } 293 } 294 throw new Resource.IOWrappedException(error); 295 } 296 297 if (handler instanceof SAXWrapper) 298 { 299 ((SAXWrapper)handler).handler = null; 300 } 301 302 attributesProxy = null; 303 handler = null; 304 lexicalHandler = null; 305 helper = null; 306 } 307 308 311 protected void traverseElement(Element element, AttributesProxy attributesProxy, DefaultHandler handler, LexicalHandler lexicalHandler) throws SAXException 312 { 313 AttributesImpl attrs = new AttributesImpl (); 315 316 if (element.hasAttributes()) 318 { 319 NamedNodeMap attributes = element.getAttributes(); 320 for (int i = 0; i < attributes.getLength(); i++) 321 { 322 Node attr = attributes.item(i); 323 String namespaceURI = attr.getNamespaceURI(); 324 if (ExtendedMetaData.XMLNS_URI.equals(namespaceURI)) 325 { 326 if (attrs.getIndex(attr.getNodeName()) < 0) 328 { 329 attrs.addAttribute("", "", attr.getNodeName(), "CDATA", attr.getNodeValue()); 330 } 331 } 332 else 333 { 334 attrs.addAttribute(namespaceURI, attr.getLocalName(), attr.getNodeName(), "CDATA", attr.getNodeValue()); 335 } 336 } 337 } 338 339 Node parent = element.getParentNode(); 340 while (parent.getNodeType() != Node.DOCUMENT_NODE) 342 { 343 if (parent.hasAttributes()) 344 { 345 NamedNodeMap attributes = parent.getAttributes(); 346 for (int i = 0; i < attributes.getLength(); i++) 347 { 348 Node attr = attributes.item(i); 349 if (ExtendedMetaData.XMLNS_URI.equals(attr.getNamespaceURI()) && attrs.getIndex(attr.getNodeName()) < 0) 351 { 352 attrs.addAttribute("", "", attr.getNodeName(), "CDATA", attr.getNodeValue()); 353 } 354 } 355 } 356 parent = parent.getParentNode(); 357 } 358 359 String namespaceURI = element.getNamespaceURI(); 361 String localName = element.getLocalName(); 362 String qname = element.getNodeName(); 363 364 handler.startElement(namespaceURI, localName , qname, attrs); 365 Node child = element.getFirstChild(); 366 while (child != null) 367 { 368 traverse(child, attributesProxy, handler, lexicalHandler); 369 child = child.getNextSibling(); 370 } 371 handler.endElement(namespaceURI, localName , qname); 372 } 373 374 protected void traverse(Node node, AttributesProxy attributesProxy, DefaultHandler handler, LexicalHandler lexicalHandler) throws SAXException 375 { 376 377 if (node == null) 378 { 379 return; 380 } 381 382 short type = node.getNodeType(); 383 switch (type) 384 { 385 case Node.DOCUMENT_NODE: 386 { 387 Document document = (Document )node; 388 handler.startDocument(); 389 Node root = document.getDocumentElement(); 390 if (lexicalHandler != null) 391 { 392 DocumentType doctype = (DocumentType )document.getDoctype(); 393 if (doctype != null) 394 { 395 String publicId = doctype.getPublicId(); 396 String systemId = doctype.getSystemId(); 397 lexicalHandler.startDTD(root.getNodeName(), publicId, systemId); 398 } 399 } 400 traverse(root, attributesProxy, handler, lexicalHandler); 401 handler.endDocument(); 402 break; 403 } 404 case Node.ELEMENT_NODE: 405 { 406 attributesProxy.setAttributes(node.getAttributes()); 407 String namespaceURI = node.getNamespaceURI(); 408 String localName = node.getLocalName(); 409 String qname = node.getNodeName(); 410 411 handler.startElement(namespaceURI, localName, qname, attributesProxy); 412 413 Node child = node.getFirstChild(); 414 while (child != null) 415 { 416 traverse(child, attributesProxy, handler, lexicalHandler); 417 child = child.getNextSibling(); 418 } 419 handler.endElement(namespaceURI, localName, qname); 420 break; 421 } 422 423 case Node.CDATA_SECTION_NODE: 424 { 425 if (lexicalHandler != null) 426 { 427 lexicalHandler.startCDATA(); 428 } 429 char[] chars = ((CDATASection )node).getData().toCharArray(); 430 handler.characters(chars, 0, chars.length); 431 if (lexicalHandler != null) 432 { 433 lexicalHandler.endCDATA(); 434 } 435 break; 436 } 437 case Node.TEXT_NODE: 438 { 439 char[] chars = node.getNodeValue().toCharArray(); 440 handler.characters(chars, 0, chars.length); 441 break; 442 } 443 case Node.COMMENT_NODE: 444 { 445 if (lexicalHandler != null) 446 { 447 char[] chars = ((Comment )node).getData().toCharArray(); 448 lexicalHandler.comment(chars, 0, chars.length); 449 } 450 } 451 } 452 } 453 454 protected static final class AttributesProxy implements Attributes 455 { 456 457 protected NamedNodeMap attributes; 458 459 460 public void setAttributes(NamedNodeMap attributes) 461 { 462 this.attributes = attributes; 463 } 464 465 public int getLength() 466 { 467 return attributes.getLength(); 468 } 469 470 public String getQName(int index) 471 { 472 Node node = attributes.item(index); 473 return (node != null) ? node.getNodeName() : null; 474 } 475 476 public String getURI(int index) 477 { 478 Node node = attributes.item(index); 479 if (node != null) 480 { 481 String namespaceURI = node.getNamespaceURI(); 482 if (ExtendedMetaData.XMLNS_URI.equals(namespaceURI)) 483 { 484 return ""; 485 } 486 return namespaceURI; 487 } 488 return null; 489 } 490 491 public String getLocalName(int index) 492 { 493 Node node = attributes.item(index); 494 if (node != null) 495 { 496 String prefix = node.getPrefix(); 497 if (ExtendedMetaData.XMLNS_PREFIX.equals(prefix)) 498 { 499 return ""; 500 } 501 return node.getLocalName(); 502 } 503 return null; 504 } 505 506 public String getType(int i) 507 { 508 return "CDATA"; 509 } 510 511 public String getType(String name) 512 { 513 return "CDATA"; 514 } 515 516 public String getType(String uri, String localName) 517 { 518 return "CDATA"; 519 } 520 521 public String getValue(int i) 522 { 523 Node node = attributes.item(i); 524 return (node != null) ? node.getNodeValue() : null; 525 } 526 527 public String getValue(String name) 528 { 529 Node node = attributes.getNamedItem(name); 530 return (node != null) ? node.getNodeValue() : null; 531 } 532 533 public String getValue(String uri, String localName) 534 { 535 Node node = attributes.getNamedItemNS(uri, localName); 536 return (node != null) ? node.getNodeValue() : null; 537 } 538 539 public int getIndex(String qName) 540 { 541 Node node = attributes.getNamedItem(qName); 542 if (node != null) 543 { 544 for (int i = 0; i < attributes.getLength(); i++) 545 { 546 Node item = attributes.item(i); 547 if (item == node) 548 { 549 return i; 550 } 551 } 552 } 553 return -1; 554 } 555 556 public int getIndex(String uri, String localPart) 557 { 558 Node node = attributes.getNamedItemNS(uri, localPart); 559 if (node != null) 560 { 561 for (int i = 0; i < attributes.getLength(); i++) 562 { 563 Node item = attributes.item(i); 564 if (item == node) 565 { 566 return i; 567 } 568 } 569 } 570 return -1; 571 } 572 } 574 } | Popular Tags |