1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Copyright 1999-2005 The Apache Software Foundation. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21 package com.sun.org.apache.xml.internal.serialize; 22 23 import java.io.FileOutputStream; 24 import java.io.IOException; 25 import java.io.OutputStream; 26 import java.io.StringWriter; 27 import java.io.UnsupportedEncodingException; 28 import java.io.Writer; 29 import java.lang.reflect.Method; 30 import java.net.HttpURLConnection; 31 import java.net.URL; 32 import java.net.URLConnection; 33 import java.util.StringTokenizer; 34 import java.util.Vector; 35 36 import com.sun.org.apache.xerces.internal.dom.AbortException; 37 import com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl; 38 import com.sun.org.apache.xerces.internal.dom.DOMErrorImpl; 39 import com.sun.org.apache.xerces.internal.dom.DOMLocatorImpl; 40 import com.sun.org.apache.xerces.internal.dom.DOMMessageFormatter; 41 import com.sun.org.apache.xerces.internal.dom.DOMNormalizer; 42 import com.sun.org.apache.xerces.internal.dom.DOMStringListImpl; 43 import org.w3c.dom.DOMConfiguration; 44 import org.w3c.dom.DOMError; 45 import org.w3c.dom.DOMErrorHandler; 46 import org.w3c.dom.DOMStringList; 47 import com.sun.org.apache.xerces.internal.impl.Constants; 48 import com.sun.org.apache.xerces.internal.impl.XMLEntityManager; 49 import com.sun.org.apache.xerces.internal.util.DOMUtil; 50 import com.sun.org.apache.xerces.internal.util.NamespaceSupport; 51 import com.sun.org.apache.xerces.internal.util.SymbolTable; 52 import com.sun.org.apache.xerces.internal.util.XML11Char; 53 import com.sun.org.apache.xerces.internal.util.XMLChar; 54 import org.w3c.dom.Attr; 55 import org.w3c.dom.Comment; 56 import org.w3c.dom.DOMException; 57 import org.w3c.dom.Document; 58 import org.w3c.dom.DocumentFragment; 59 import org.w3c.dom.Element; 60 import org.w3c.dom.NamedNodeMap; 61 import org.w3c.dom.Node; 62 import org.w3c.dom.ProcessingInstruction; 63 import org.w3c.dom.ls.LSException; 64 import org.w3c.dom.ls.LSOutput; 65 import org.w3c.dom.ls.LSSerializer; 66 import org.w3c.dom.ls.LSSerializerFilter; 67 68 69 /** 70 * EXPERIMENTAL: Implemenatation of DOM Level 3 org.w3c.ls.LSSerializer by delegating serialization 71 * calls to <CODE>XMLSerializer</CODE>. 72 * LSSerializer provides an API for serializing (writing) a DOM document out in an 73 * XML document. The XML data is written to an output stream. 74 * During serialization of XML data, namespace fixup is done when possible as 75 * defined in DOM Level 3 Core, Appendix B. 76 * 77 * @author Elena Litani, IBM 78 * @author Gopal Sharma, Sun Microsystems 79 * @author Arun Yadav, Sun Microsystems 80 * @author Sunitha Reddy, Sun Microsystems 81 * @version $Id: DOMSerializerImpl.java,v 1.11 2010-11-01 04:40:36 joehw Exp $ 82 */ 83 public class DOMSerializerImpl implements LSSerializer, DOMConfiguration { 84 85 // TODO: When DOM Level 3 goes to REC replace method calls using 86 // reflection for: getXmlEncoding, getInputEncoding and getXmlEncoding 87 // with regular static calls on the Document object. 88 89 // data 90 // serializer 91 private XMLSerializer serializer; 92 93 // XML 1.1 serializer 94 private XML11Serializer xml11Serializer; 95 96 //Recognized parameters 97 private DOMStringList fRecognizedParameters; 98 99 /** REVISIT: Currently we handle 3 different configurations, would be nice just have one configuration 100 * that has different recognized parameters depending if it is used in Core/LS. 101 */ 102 protected short features = 0; 103 104 protected final static short NAMESPACES = 0x1<<0; 105 protected final static short WELLFORMED = 0x1<<1; 106 protected final static short ENTITIES = 0x1<<2; 107 protected final static short CDATA = 0x1<<3; 108 protected final static short SPLITCDATA = 0x1<<4; 109 protected final static short COMMENTS = 0x1<<5; 110 protected final static short DISCARDDEFAULT = 0x1<<6; 111 protected final static short INFOSET = 0x1<<7; 112 protected final static short XMLDECL = 0x1<<8; 113 protected final static short NSDECL = 0x1<<9; 114 protected final static short DOM_ELEMENT_CONTENT_WHITESPACE = 0x1<<10; 115 protected final static short FORMAT_PRETTY_PRINT = 0x1<<11; 116 117 // well-formness checking 118 private DOMErrorHandler fErrorHandler = null; 119 private final DOMErrorImpl fError = new DOMErrorImpl(); 120 private final DOMLocatorImpl fLocator = new DOMLocatorImpl(); 121 122 /** 123 * Constructs a new LSSerializer. 124 * The constructor turns on the namespace support in <code>XMLSerializer</code> and 125 * initializes the following fields: fNSBinder, fLocalNSBinder, fSymbolTable, 126 * fEmptySymbol, fXmlSymbol, fXmlnsSymbol, fNamespaceCounter, fFeatures. 127 */ 128 public DOMSerializerImpl() { 129 // set default features 130 features |= NAMESPACES; 131 features |= ENTITIES; 132 features |= COMMENTS; 133 features |= CDATA; 134 features |= SPLITCDATA; 135 features |= WELLFORMED; 136 features |= NSDECL; 137 features |= DOM_ELEMENT_CONTENT_WHITESPACE; 138 features |= DISCARDDEFAULT; 139 features |= XMLDECL; 140 141 serializer = new XMLSerializer(); 142 initSerializer(serializer); 143 } 144 145 146 147 // 148 // LSSerializer methods 149 // 150 151 public DOMConfiguration getDomConfig(){ 152 return this; 153 } 154 155 /** DOM L3-EXPERIMENTAL: 156 * Setter for boolean and object parameters 157 */ 158 public void setParameter(String name, Object value) throws DOMException { 159 if (value instanceof Boolean) { 160 boolean state = ((Boolean) value).booleanValue(); 161 if (name.equalsIgnoreCase(Constants.DOM_INFOSET)){ 162 if (state){ 163 features &= ~ENTITIES; 164 features &= ~CDATA; 165 features |= NAMESPACES; 166 features |= NSDECL; 167 features |= WELLFORMED; 168 features |= COMMENTS; 169 } 170 // false does not have any effect 171 } else if (name.equalsIgnoreCase(Constants.DOM_XMLDECL)) { 172 features = 173 (short) (state ? features | XMLDECL : features & ~XMLDECL); 174 } else if (name.equalsIgnoreCase(Constants.DOM_NAMESPACES)) { 175 features = 176 (short) (state 177 ? features | NAMESPACES 178 : features & ~NAMESPACES); 179 serializer.fNamespaces = state; 180 } else if (name.equalsIgnoreCase(Constants.DOM_SPLIT_CDATA)) { 181 features = 182 (short) (state 183 ? features | SPLITCDATA 184 : features & ~SPLITCDATA); 185 } else if (name.equalsIgnoreCase(Constants.DOM_DISCARD_DEFAULT_CONTENT)) { 186 features = 187 (short) (state 188 ? features | DISCARDDEFAULT 189 : features & ~DISCARDDEFAULT); 190 } else if (name.equalsIgnoreCase(Constants.DOM_WELLFORMED)) { 191 features = 192 (short) (state 193 ? features | WELLFORMED 194 : features & ~WELLFORMED); 195 } else if (name.equalsIgnoreCase(Constants.DOM_ENTITIES)){ 196 features = 197 (short) (state 198 ? features | ENTITIES 199 : features & ~ENTITIES); 200 } 201 else if (name.equalsIgnoreCase(Constants.DOM_CDATA_SECTIONS)){ 202 features = 203 (short) (state 204 ? features | CDATA 205 : features & ~CDATA); 206 } 207 else if (name.equalsIgnoreCase(Constants.DOM_COMMENTS)){ 208 features = 209 (short) (state 210 ? features | COMMENTS 211 : features & ~COMMENTS); 212 } 213 else if (name.equalsIgnoreCase(Constants.DOM_FORMAT_PRETTY_PRINT)){ 214 features = 215 (short) (state 216 ? features | FORMAT_PRETTY_PRINT 217 : features & ~FORMAT_PRETTY_PRINT); 218 } 219 else if (name.equalsIgnoreCase(Constants.DOM_CANONICAL_FORM) 220 || name.equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA) 221 || name.equalsIgnoreCase(Constants.DOM_VALIDATE) 222 || name.equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION) 223 || name.equalsIgnoreCase(Constants.DOM_DATATYPE_NORMALIZATION)) { 224 // || name.equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)) { 225 // true is not supported 226 if (state) { 227 String msg = 228 DOMMessageFormatter.formatMessage( 229 DOMMessageFormatter.DOM_DOMAIN, 230 "FEATURE_NOT_SUPPORTED", 231 new Object[] { name }); 232 throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg); 233 } 234 }else if ( 235 name.equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS)) { 236 //namespace-declaration has effect only if namespaces is true 237 features = 238 (short) (state 239 ? features | NSDECL 240 : features & ~NSDECL); 241 serializer.fNamespacePrefixes = state; 242 } else if (name.equalsIgnoreCase(Constants.DOM_ELEMENT_CONTENT_WHITESPACE) 243 || name.equalsIgnoreCase(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) { 244 // false is not supported 245 if (!state) { 246 String msg = 247 DOMMessageFormatter.formatMessage( 248 DOMMessageFormatter.DOM_DOMAIN, 249 "FEATURE_NOT_SUPPORTED", 250 new Object[] { name }); 251 throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg); 252 } 253 } else { 254 String msg = 255 DOMMessageFormatter.formatMessage( 256 DOMMessageFormatter.DOM_DOMAIN, 257 "FEATURE_NOT_FOUND", 258 new Object[] { name }); 259 throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg); 260 } 261 } else if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER)) { 262 if (value == null || value instanceof DOMErrorHandler) { 263 fErrorHandler = (DOMErrorHandler)value; 264 } else { 265 String msg = 266 DOMMessageFormatter.formatMessage( 267 DOMMessageFormatter.DOM_DOMAIN, 268 "TYPE_MISMATCH_ERR", 269 new Object[] { name }); 270 throw new DOMException(DOMException.TYPE_MISMATCH_ERR, msg); 271 } 272 } else if ( 273 name.equalsIgnoreCase(Constants.DOM_RESOURCE_RESOLVER) 274 || name.equalsIgnoreCase(Constants.DOM_SCHEMA_LOCATION) 275 || name.equalsIgnoreCase(Constants.DOM_SCHEMA_TYPE) 276 || name.equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS) 277 && value != null) { 278 String msg = 279 DOMMessageFormatter.formatMessage( 280 DOMMessageFormatter.DOM_DOMAIN, 281 "FEATURE_NOT_SUPPORTED", 282 new Object[] { name }); 283 throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg); 284 } else { 285 String msg = 286 DOMMessageFormatter.formatMessage( 287 DOMMessageFormatter.DOM_DOMAIN, 288 "FEATURE_NOT_FOUND", 289 new Object[] { name }); 290 throw new DOMException(DOMException.NOT_FOUND_ERR, msg); 291 } 292 } 293 294 /** DOM L3-EXPERIMENTAL: 295 * Check if parameter can be set 296 */ 297 public boolean canSetParameter(String name, Object state) { 298 299 if (state == null) { 300 return true; 301 } 302 303 if (state instanceof Boolean) { 304 boolean value = ((Boolean) state).booleanValue(); 305 306 if (name.equalsIgnoreCase(Constants.DOM_NAMESPACES) 307 || name.equalsIgnoreCase(Constants.DOM_SPLIT_CDATA) 308 || name.equalsIgnoreCase(Constants.DOM_DISCARD_DEFAULT_CONTENT) 309 || name.equalsIgnoreCase(Constants.DOM_XMLDECL) 310 || name.equalsIgnoreCase(Constants.DOM_WELLFORMED) 311 || name.equalsIgnoreCase(Constants.DOM_INFOSET) 312 || name.equalsIgnoreCase(Constants.DOM_ENTITIES) 313 || name.equalsIgnoreCase(Constants.DOM_CDATA_SECTIONS) 314 || name.equalsIgnoreCase(Constants.DOM_COMMENTS) 315 || name.equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS) 316 || name.equalsIgnoreCase(Constants.DOM_FORMAT_PRETTY_PRINT)) { 317 // both values supported 318 return true; 319 } else if (name.equalsIgnoreCase(Constants.DOM_CANONICAL_FORM) 320 || name.equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA) 321 || name.equalsIgnoreCase(Constants.DOM_VALIDATE) 322 || name.equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION) 323 || name.equalsIgnoreCase(Constants.DOM_DATATYPE_NORMALIZATION)) { 324 // || name.equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)) { 325 // true is not supported 326 return !value; 327 } else if (name.equalsIgnoreCase(Constants.DOM_ELEMENT_CONTENT_WHITESPACE) 328 || name.equalsIgnoreCase(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) { 329 // false is not supported 330 return value; 331 } 332 } else if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER) && 333 state == null || state instanceof DOMErrorHandler) { 334 return true; 335 } 336 337 return false; 338 } 339 340 /** 341 * DOM Level 3 Core CR - Experimental. 342 * 343 * The list of the parameters supported by this 344 * <code>DOMConfiguration</code> object and for which at least one value 345 * can be set by the application. Note that this list can also contain 346 * parameter names defined outside this specification. 347 */ 348 public DOMStringList getParameterNames() { 349 350 if (fRecognizedParameters == null){ 351 Vector parameters = new Vector(); 352 353 //Add DOM recognized parameters 354 //REVISIT: Would have been nice to have a list of 355 //recognized parameters. 356 parameters.add(Constants.DOM_NAMESPACES); 357 parameters.add(Constants.DOM_SPLIT_CDATA); 358 parameters.add(Constants.DOM_DISCARD_DEFAULT_CONTENT); 359 parameters.add(Constants.DOM_XMLDECL); 360 parameters.add(Constants.DOM_CANONICAL_FORM); 361 parameters.add(Constants.DOM_VALIDATE_IF_SCHEMA); 362 parameters.add(Constants.DOM_VALIDATE); 363 parameters.add(Constants.DOM_CHECK_CHAR_NORMALIZATION); 364 parameters.add(Constants.DOM_DATATYPE_NORMALIZATION); 365 parameters.add(Constants.DOM_FORMAT_PRETTY_PRINT); 366 //parameters.add(Constants.DOM_NORMALIZE_CHARACTERS); 367 parameters.add(Constants.DOM_WELLFORMED); 368 parameters.add(Constants.DOM_INFOSET); 369 parameters.add(Constants.DOM_NAMESPACE_DECLARATIONS); 370 parameters.add(Constants.DOM_ELEMENT_CONTENT_WHITESPACE); 371 parameters.add(Constants.DOM_ENTITIES); 372 parameters.add(Constants.DOM_CDATA_SECTIONS); 373 parameters.add(Constants.DOM_COMMENTS); 374 parameters.add(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS); 375 parameters.add(Constants.DOM_ERROR_HANDLER); 376 //parameters.add(Constants.DOM_SCHEMA_LOCATION); 377 //parameters.add(Constants.DOM_SCHEMA_TYPE); 378 379 //Add recognized xerces features and properties 380 381 fRecognizedParameters = new DOMStringListImpl(parameters); 382 383 } 384 385 return fRecognizedParameters; 386 } 387 388 /** DOM L3-EXPERIMENTAL: 389 * Getter for boolean and object parameters 390 */ 391 public Object getParameter(String name) throws DOMException { 392 393 if(name.equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)){ 394 return null; 395 } else if (name.equalsIgnoreCase(Constants.DOM_COMMENTS)) { 396 return ((features & COMMENTS) != 0) ? Boolean.TRUE : Boolean.FALSE; 397 } else if (name.equalsIgnoreCase(Constants.DOM_NAMESPACES)) { 398 return (features & NAMESPACES) != 0 ? Boolean.TRUE : Boolean.FALSE; 399 } else if (name.equalsIgnoreCase(Constants.DOM_XMLDECL)) { 400 return (features & XMLDECL) != 0 ? Boolean.TRUE : Boolean.FALSE; 401 } else if (name.equalsIgnoreCase(Constants.DOM_CDATA_SECTIONS)) { 402 return (features & CDATA) != 0 ? Boolean.TRUE : Boolean.FALSE; 403 } else if (name.equalsIgnoreCase(Constants.DOM_ENTITIES)) { 404 return (features & ENTITIES) != 0 ? Boolean.TRUE : Boolean.FALSE; 405 } else if (name.equalsIgnoreCase(Constants.DOM_SPLIT_CDATA)) { 406 return (features & SPLITCDATA) != 0 ? Boolean.TRUE : Boolean.FALSE; 407 } else if (name.equalsIgnoreCase(Constants.DOM_WELLFORMED)) { 408 return (features & WELLFORMED) != 0 ? Boolean.TRUE : Boolean.FALSE; 409 } else if (name.equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS)) { 410 return (features & NSDECL) != 0 ? Boolean.TRUE : Boolean.FALSE; 411 } else if (name.equalsIgnoreCase(Constants.DOM_FORMAT_PRETTY_PRINT)) { 412 return (features & FORMAT_PRETTY_PRINT) != 0 ? Boolean.TRUE : Boolean.FALSE; 413 } else if (name.equalsIgnoreCase(Constants.DOM_ELEMENT_CONTENT_WHITESPACE) || 414 name.equalsIgnoreCase(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) { 415 return Boolean.TRUE; 416 }else if (name.equalsIgnoreCase(Constants.DOM_DISCARD_DEFAULT_CONTENT)){ 417 return ((features & DISCARDDEFAULT)!=0)?Boolean.TRUE:Boolean.FALSE; 418 }else if (name.equalsIgnoreCase(Constants.DOM_INFOSET)){ 419 if ((features & ENTITIES) == 0 && 420 (features & CDATA) == 0 && 421 (features & NAMESPACES) != 0 && 422 (features & NSDECL) != 0 && 423 (features & WELLFORMED) != 0 && 424 (features & COMMENTS) != 0) { 425 return Boolean.TRUE; 426 } 427 return Boolean.FALSE; 428 } else if (name.equalsIgnoreCase(Constants.DOM_CANONICAL_FORM) 429 || name.equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA) 430 || name.equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION) 431 || name.equalsIgnoreCase(Constants.DOM_VALIDATE) 432 || name.equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA) 433 || name.equalsIgnoreCase(Constants.DOM_DATATYPE_NORMALIZATION)) { 434 return Boolean.FALSE; 435 } else if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER)) { 436 return fErrorHandler; 437 } else if ( 438 name.equalsIgnoreCase(Constants.DOM_RESOURCE_RESOLVER) 439 || name.equalsIgnoreCase(Constants.DOM_SCHEMA_LOCATION) 440 || name.equalsIgnoreCase(Constants.DOM_SCHEMA_TYPE)) { 441 String msg = 442 DOMMessageFormatter.formatMessage( 443 DOMMessageFormatter.DOM_DOMAIN, 444 "FEATURE_NOT_SUPPORTED", 445 new Object[] { name }); 446 throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg); 447 } else { 448 String msg = 449 DOMMessageFormatter.formatMessage( 450 DOMMessageFormatter.DOM_DOMAIN, 451 "FEATURE_NOT_FOUND", 452 new Object[] { name }); 453 throw new DOMException(DOMException.NOT_FOUND_ERR, msg); 454 } 455 } 456 457 458 /** 459 * DOM L3 EXPERIMENTAL: 460 * Serialize the specified node as described above in the description of 461 * <code>LSSerializer</code>. The result of serializing the node is 462 * returned as a string. Writing a Document or Entity node produces a 463 * serialized form that is well formed XML. Writing other node types 464 * produces a fragment of text in a form that is not fully defined by 465 * this document, but that should be useful to a human for debugging or 466 * diagnostic purposes. 467 * @param wnode The node to be written. 468 * @return Returns the serialized data 469 * @exception DOMException 470 * DOMSTRING_SIZE_ERR: The resulting string is too long to fit in a 471 * <code>DOMString</code>. 472 * @exception LSException 473 * SERIALIZE_ERR: Unable to serialize the node. DOM applications should 474 * attach a <code>DOMErrorHandler</code> using the parameter 475 * "<i>error-handler</i>" to get details on error. 476 */ 477 public String writeToString(Node wnode) throws DOMException, LSException { 478 // determine which serializer to use: 479 Document doc = (wnode.getNodeType() == Node.DOCUMENT_NODE)?(Document)wnode:wnode.getOwnerDocument(); 480 Method getVersion = null; 481 XMLSerializer ser = null; 482 String ver = null; 483 // this should run under JDK 1.1.8... 484 try { 485 getVersion = doc.getClass().getMethod("getXmlVersion", new Class[]{}); 486 if(getVersion != null ) { 487 ver = (String)getVersion.invoke(doc, (Object[]) null); 488 } 489 } catch (Exception e) { 490 // no way to test the version... 491 // ignore the exception 492 } 493 if(ver != null && ver.equals("1.1")) { 494 if(xml11Serializer == null) { 495 xml11Serializer = new XML11Serializer(); 496 initSerializer(xml11Serializer); 497 } 498 // copy setting from "main" serializer to XML 1.1 serializer 499 copySettings(serializer, xml11Serializer); 500 ser = xml11Serializer; 501 } else { 502 ser = serializer; 503 } 504 505 StringWriter destination = new StringWriter(); 506 try { 507 prepareForSerialization(ser, wnode); 508 ser._format.setEncoding("UTF-16"); 509 ser.setOutputCharStream(destination); 510 if (wnode.getNodeType() == Node.DOCUMENT_NODE) { 511 ser.serialize((Document)wnode); 512 } 513 else if (wnode.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE) { 514 ser.serialize((DocumentFragment)wnode); 515 } 516 else if (wnode.getNodeType() == Node.ELEMENT_NODE) { 517 ser.serialize((Element)wnode); 518 } 519 else if (wnode.getNodeType() == Node.TEXT_NODE || 520 wnode.getNodeType() == Node.COMMENT_NODE || 521 wnode.getNodeType() == Node.ENTITY_REFERENCE_NODE || 522 wnode.getNodeType() == Node.CDATA_SECTION_NODE || 523 wnode.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE ) { 524 ser.serialize(wnode); 525 } 526 else { 527 String msg = DOMMessageFormatter.formatMessage( 528 DOMMessageFormatter.SERIALIZER_DOMAIN, 529 "unable-to-serialize-node", null); 530 if (ser.fDOMErrorHandler != null) { 531 DOMErrorImpl error = new DOMErrorImpl(); 532 error.fType = "unable-to-serialize-node"; 533 error.fMessage = msg; 534 error.fSeverity = DOMError.SEVERITY_FATAL_ERROR; 535 ser.fDOMErrorHandler.handleError(error); 536 } 537 throw new LSException(LSException.SERIALIZE_ERR, msg); 538 } 539 } catch (LSException lse) { 540 // Rethrow LSException. 541 throw lse; 542 } catch (AbortException e) { 543 return null; 544 } catch (RuntimeException e) { 545 throw (LSException) new LSException(LSException.SERIALIZE_ERR, e.toString()).initCause(e); 546 } catch (IOException ioe) { 547 // REVISIT: A generic IOException doesn't provide enough information 548 // to determine that the serialized document is too large to fit 549 // into a string. This could have thrown for some other reason. -- mrglavas 550 String msg = DOMMessageFormatter.formatMessage( 551 DOMMessageFormatter.DOM_DOMAIN, 552 "STRING_TOO_LONG", 553 new Object[] { ioe.getMessage()}); 554 throw (DOMException) new DOMException(DOMException.DOMSTRING_SIZE_ERR, msg).initCause(ioe); 555 } 556 557 return destination.toString(); 558 } 559 560 /** 561 * DOM L3 EXPERIMENTAL: 562 * The end-of-line sequence of characters to be used in the XML being 563 * written out. The only permitted values are these: 564 * <dl> 565 * <dt><code>null</code></dt> 566 * <dd> 567 * Use a default end-of-line sequence. DOM implementations should choose 568 * the default to match the usual convention for text files in the 569 * environment being used. Implementations must choose a default 570 * sequence that matches one of those allowed by 2.11 "End-of-Line 571 * Handling". </dd> 572 * <dt>CR</dt> 573 * <dd>The carriage-return character (#xD).</dd> 574 * <dt>CR-LF</dt> 575 * <dd> The 576 * carriage-return and line-feed characters (#xD #xA). </dd> 577 * <dt>LF</dt> 578 * <dd> The line-feed 579 * character (#xA). </dd> 580 * </dl> 581 * <br>The default value for this attribute is <code>null</code>. 582 */ 583 public void setNewLine(String newLine) { 584 serializer._format.setLineSeparator(newLine); 585 } 586 587 588 /** 589 * DOM L3 EXPERIMENTAL: 590 * The end-of-line sequence of characters to be used in the XML being 591 * written out. The only permitted values are these: 592 * <dl> 593 * <dt><code>null</code></dt> 594 * <dd> 595 * Use a default end-of-line sequence. DOM implementations should choose 596 * the default to match the usual convention for text files in the 597 * environment being used. Implementations must choose a default 598 * sequence that matches one of those allowed by 2.11 "End-of-Line 599 * Handling". </dd> 600 * <dt>CR</dt> 601 * <dd>The carriage-return character (#xD).</dd> 602 * <dt>CR-LF</dt> 603 * <dd> The 604 * carriage-return and line-feed characters (#xD #xA). </dd> 605 * <dt>LF</dt> 606 * <dd> The line-feed 607 * character (#xA). </dd> 608 * </dl> 609 * <br>The default value for this attribute is <code>null</code>. 610 */ 611 public String getNewLine() { 612 return serializer._format.getLineSeparator(); 613 } 614 615 616 /** 617 * When the application provides a filter, the serializer will call out 618 * to the filter before serializing each Node. Attribute nodes are never 619 * passed to the filter. The filter implementation can choose to remove 620 * the node from the stream or to terminate the serialization early. 621 */ 622 public LSSerializerFilter getFilter(){ 623 return serializer.fDOMFilter; 624 } 625 /** 626 * When the application provides a filter, the serializer will call out 627 * to the filter before serializing each Node. Attribute nodes are never 628 * passed to the filter. The filter implementation can choose to remove 629 * the node from the stream or to terminate the serialization early. 630 */ 631 public void setFilter(LSSerializerFilter filter){ 632 serializer.fDOMFilter = filter; 633 } 634 635 // this initializes a newly-created serializer 636 private void initSerializer(XMLSerializer ser) { 637 ser.fNSBinder = new NamespaceSupport(); 638 ser.fLocalNSBinder = new NamespaceSupport(); 639 ser.fSymbolTable = new SymbolTable(); 640 } 641 642 // copies all settings that could have been modified 643 // by calls to LSSerializer methods from one serializer to another. 644 // IMPORTANT: if new methods are implemented or more settings of 645 // the serializer are made alterable, this must be 646 // reflected in this method! 647 private void copySettings(XMLSerializer src, XMLSerializer dest) { 648 dest.fDOMErrorHandler = fErrorHandler; 649 dest._format.setEncoding(src._format.getEncoding()); 650 dest._format.setLineSeparator(src._format.getLineSeparator()); 651 dest.fDOMFilter = src.fDOMFilter; 652 }//copysettings 653 654 /** 655 * Serialize the specified node as described above in the general 656 * description of the <code>LSSerializer</code> interface. The output 657 * is written to the supplied <code>LSOutput</code>. 658 * <br> When writing to a <code>LSOutput</code>, the encoding is found by 659 * looking at the encoding information that is reachable through the 660 * <code>LSOutput</code> and the item to be written (or its owner 661 * document) in this order: 662 * <ol> 663 * <li> <code>LSOutput.encoding</code>, 664 * </li> 665 * <li> 666 * <code>Document.actualEncoding</code>, 667 * </li> 668 * <li> 669 * <code>Document.xmlEncoding</code>. 670 * </li> 671 * </ol> 672 * <br> If no encoding is reachable through the above properties, a 673 * default encoding of "UTF-8" will be used. 674 * <br> If the specified encoding is not supported an 675 * "unsupported-encoding" error is raised. 676 * <br> If no output is specified in the <code>LSOutput</code>, a 677 * "no-output-specified" error is raised. 678 * @param node The node to serialize. 679 * @param destination The destination for the serialized DOM. 680 * @return Returns <code>true</code> if <code>node</code> was 681 * successfully serialized and <code>false</code> in case the node 682 * couldn't be serialized. 683 */ 684 public boolean write(Node node, LSOutput destination) throws LSException{ 685 686 if (node == null) 687 return false; 688 689 Method getVersion = null; 690 XMLSerializer ser = null; 691 String ver = null; 692 Document fDocument =(node.getNodeType() == Node.DOCUMENT_NODE) 693 ? (Document) node 694 : node.getOwnerDocument(); 695 // this should run under JDK 1.1.8... 696 try { 697 getVersion = fDocument.getClass().getMethod("getXmlVersion", new Class[] {}); 698 if (getVersion != null) { 699 ver = (String) getVersion.invoke(fDocument, (Object[]) null); 700 } 701 } catch (Exception e) { 702 //no way to test the version... 703 //ignore the exception 704 } 705 //determine which serializer to use: 706 if (ver != null && ver.equals("1.1")) { 707 if (xml11Serializer == null) { 708 xml11Serializer = new XML11Serializer(); 709 initSerializer(xml11Serializer); 710 } 711 //copy setting from "main" serializer to XML 1.1 serializer 712 copySettings(serializer, xml11Serializer); 713 ser = xml11Serializer; 714 } else { 715 ser = serializer; 716 } 717 718 String encoding = null; 719 if ((encoding = destination.getEncoding()) == null) { 720 try { 721 Method getEncoding = 722 fDocument.getClass().getMethod("getInputEncoding", new Class[] {}); 723 if (getEncoding != null) { 724 encoding = (String) getEncoding.invoke(fDocument, (Object[]) null); 725 } 726 } catch (Exception e) { 727 // ignore the exception 728 } 729 if (encoding == null) { 730 try { 731 Method getEncoding = 732 fDocument.getClass().getMethod("getXmlEncoding", new Class[] {}); 733 if (getEncoding != null) { 734 encoding = (String) getEncoding.invoke(fDocument, (Object[]) null); 735 } 736 } catch (Exception e) { 737 // ignore the exception 738 } 739 if (encoding == null) { 740 encoding = "UTF-8"; 741 } 742 } 743 } 744 try { 745 prepareForSerialization(ser, node); 746 ser._format.setEncoding(encoding); 747 OutputStream outputStream = destination.getByteStream(); 748 Writer writer = destination.getCharacterStream(); 749 String uri = destination.getSystemId(); 750 if (writer == null) { 751 if (outputStream == null) { 752 if (uri == null) { 753 String msg = DOMMessageFormatter.formatMessage( 754 DOMMessageFormatter.SERIALIZER_DOMAIN, 755 "no-output-specified", null); 756 if (ser.fDOMErrorHandler != null) { 757 DOMErrorImpl error = new DOMErrorImpl(); 758 error.fType = "no-output-specified"; 759 error.fMessage = msg; 760 error.fSeverity = DOMError.SEVERITY_FATAL_ERROR; 761 ser.fDOMErrorHandler.handleError(error); 762 } 763 throw new LSException(LSException.SERIALIZE_ERR, msg); 764 } 765 else { 766 // URI was specified. Handle relative URIs. 767 String expanded = XMLEntityManager.expandSystemId(uri, null, true); 768 URL url = new URL(expanded != null ? expanded : uri); 769 OutputStream out = null; 770 String protocol = url.getProtocol(); 771 String host = url.getHost(); 772 // Use FileOutputStream if this URI is for a local file. 773 if (protocol.equals("file") 774 && (host == null || host.length() == 0 || host.equals("localhost"))) { 775 out = new FileOutputStream(getPathWithoutEscapes(url.getFile())); 776 } 777 // Try to write to some other kind of URI. Some protocols 778 // won't support this, though HTTP should work. 779 else { 780 URLConnection urlCon = url.openConnection(); 781 urlCon.setDoInput(false); 782 urlCon.setDoOutput(true); 783 urlCon.setUseCaches(false); // Enable tunneling. 784 if (urlCon instanceof HttpURLConnection) { 785 // The DOM L3 LS CR says if we are writing to an HTTP URI 786 // it is to be done with an HTTP PUT. 787 HttpURLConnection httpCon = (HttpURLConnection) urlCon; 788 httpCon.setRequestMethod("PUT"); 789 } 790 out = urlCon.getOutputStream(); 791 } 792 ser.setOutputByteStream(out); 793 } 794 } 795 else { 796 // byte stream was specified 797 ser.setOutputByteStream(outputStream); 798 } 799 } 800 else { 801 // character stream is specified 802 ser.setOutputCharStream(writer); 803 } 804 805 if (node.getNodeType() == Node.DOCUMENT_NODE) 806 ser.serialize((Document) node); 807 else if (node.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE) 808 ser.serialize((DocumentFragment) node); 809 else if (node.getNodeType() == Node.ELEMENT_NODE) 810 ser.serialize((Element) node); 811 else if (node.getNodeType() == Node.TEXT_NODE || 812 node.getNodeType() == Node.COMMENT_NODE || 813 node.getNodeType() == Node.ENTITY_REFERENCE_NODE || 814 node.getNodeType() == Node.CDATA_SECTION_NODE || 815 node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE ) { 816 ser.serialize(node); 817 } 818 else 819 return false; 820 } catch( UnsupportedEncodingException ue) { 821 if (ser.fDOMErrorHandler != null) { 822 DOMErrorImpl error = new DOMErrorImpl(); 823 error.fException = ue; 824 error.fType = "unsupported-encoding"; 825 error.fMessage = ue.getMessage(); 826 error.fSeverity = DOMError.SEVERITY_FATAL_ERROR; 827 ser.fDOMErrorHandler.handleError(error); 828 } 829 throw new LSException(LSException.SERIALIZE_ERR, 830 DOMMessageFormatter.formatMessage( 831 DOMMessageFormatter.SERIALIZER_DOMAIN, 832 "unsupported-encoding", null)); 833 //return false; 834 } catch (LSException lse) { 835 // Rethrow LSException. 836 throw lse; 837 } catch (AbortException e) { 838 return false; 839 } catch (RuntimeException e) { 840 throw (LSException) DOMUtil.createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace(); 841 } catch (Exception e) { 842 if (ser.fDOMErrorHandler != null) { 843 DOMErrorImpl error = new DOMErrorImpl(); 844 error.fException = e; 845 error.fMessage = e.getMessage(); 846 error.fSeverity = DOMError.SEVERITY_ERROR; 847 ser.fDOMErrorHandler.handleError(error); 848 849 } 850 throw (LSException) DOMUtil.createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace(); 851 } 852 return true; 853 854 } //write 855 856 /** 857 * Serialize the specified node as described above in the general 858 * description of the <code>LSSerializer</code> interface. The output 859 * is written to the supplied URI. 860 * <br> When writing to a URI, the encoding is found by looking at the 861 * encoding information that is reachable through the item to be written 862 * (or its owner document) in this order: 863 * <ol> 864 * <li> 865 * <code>Document.inputEncoding</code>, 866 * </li> 867 * <li> 868 * <code>Document.xmlEncoding</code>. 869 * </li> 870 * </ol> 871 * <br> If no encoding is reachable through the above properties, a 872 * default encoding of "UTF-8" will be used. 873 * <br> If the specified encoding is not supported an 874 * "unsupported-encoding" error is raised. 875 * @param node The node to serialize. 876 * @param URI The URI to write to. 877 * @return Returns <code>true</code> if <code>node</code> was 878 * successfully serialized and <code>false</code> in case the node 879 * couldn't be serialized. 880 */ 881 public boolean writeToURI(Node node, String URI) throws LSException{ 882 if (node == null){ 883 return false; 884 } 885 886 Method getXmlVersion = null; 887 XMLSerializer ser = null; 888 String ver = null; 889 String encoding = null; 890 891 Document fDocument =(node.getNodeType() == Node.DOCUMENT_NODE) 892 ? (Document) node 893 : node.getOwnerDocument(); 894 // this should run under JDK 1.1.8... 895 try { 896 getXmlVersion = 897 fDocument.getClass().getMethod("getXmlVersion", new Class[] {}); 898 if (getXmlVersion != null) { 899 ver = (String) getXmlVersion.invoke(fDocument, (Object[]) null); 900 } 901 } catch (Exception e) { 902 // no way to test the version... 903 // ignore the exception 904 } 905 if (ver != null && ver.equals("1.1")) { 906 if (xml11Serializer == null) { 907 xml11Serializer = new XML11Serializer(); 908 initSerializer(xml11Serializer); 909 } 910 // copy setting from "main" serializer to XML 1.1 serializer 911 copySettings(serializer, xml11Serializer); 912 ser = xml11Serializer; 913 } else { 914 ser = serializer; 915 } 916 917 try { 918 Method getEncoding = 919 fDocument.getClass().getMethod("getInputEncoding", new Class[] {}); 920 if (getEncoding != null) { 921 encoding = (String) getEncoding.invoke(fDocument, (Object[]) null); 922 } 923 } catch (Exception e) { 924 // ignore the exception 925 } 926 if (encoding == null) { 927 try { 928 Method getEncoding = 929 fDocument.getClass().getMethod("getXmlEncoding", new Class[] {}); 930 if (getEncoding != null) { 931 encoding = (String) getEncoding.invoke(fDocument, (Object[]) null); 932 } 933 } catch (Exception e) { 934 // ignore the exception 935 } 936 if (encoding == null) { 937 encoding = "UTF-8"; 938 } 939 } 940 941 try { 942 prepareForSerialization(ser, node); 943 ser._format.setEncoding(encoding); 944 945 // URI was specified. Handle relative URIs. 946 String expanded = XMLEntityManager.expandSystemId(URI, null, true); 947 URL url = new URL(expanded != null ? expanded : URI); 948 OutputStream out = null; 949 String protocol = url.getProtocol(); 950 String host = url.getHost(); 951 // Use FileOutputStream if this URI is for a local file. 952 if (protocol.equals("file") 953 && (host == null || host.length() == 0 || host.equals("localhost"))) { 954 out = new FileOutputStream(getPathWithoutEscapes(url.getFile())); 955 } 956 // Try to write to some other kind of URI. Some protocols 957 // won't support this, though HTTP should work. 958 else { 959 URLConnection urlCon = url.openConnection(); 960 urlCon.setDoInput(false); 961 urlCon.setDoOutput(true); 962 urlCon.setUseCaches(false); // Enable tunneling. 963 if (urlCon instanceof HttpURLConnection) { 964 // The DOM L3 LS CR says if we are writing to an HTTP URI 965 // it is to be done with an HTTP PUT. 966 HttpURLConnection httpCon = (HttpURLConnection) urlCon; 967 httpCon.setRequestMethod("PUT"); 968 } 969 out = urlCon.getOutputStream(); 970 } 971 ser.setOutputByteStream(out); 972 973 if (node.getNodeType() == Node.DOCUMENT_NODE) 974 ser.serialize((Document) node); 975 else if (node.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE) 976 ser.serialize((DocumentFragment) node); 977 else if (node.getNodeType() == Node.ELEMENT_NODE) 978 ser.serialize((Element) node); 979 else if (node.getNodeType() == Node.TEXT_NODE || 980 node.getNodeType() == Node.COMMENT_NODE || 981 node.getNodeType() == Node.ENTITY_REFERENCE_NODE || 982 node.getNodeType() == Node.CDATA_SECTION_NODE || 983 node.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE ) { 984 ser.serialize(node); 985 } 986 else 987 return false; 988 } catch (LSException lse) { 989 // Rethrow LSException. 990 throw lse; 991 } catch (AbortException e) { 992 return false; 993 } catch (RuntimeException e) { 994 throw (LSException) DOMUtil.createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace(); 995 } catch (Exception e) { 996 if (ser.fDOMErrorHandler != null) { 997 DOMErrorImpl error = new DOMErrorImpl(); 998 error.fException = e; 999 error.fMessage = e.getMessage(); 1000 error.fSeverity = DOMError.SEVERITY_ERROR; 1001 ser.fDOMErrorHandler.handleError(error); 1002 } 1003 throw (LSException) DOMUtil.createLSException(LSException.SERIALIZE_ERR, e).fillInStackTrace(); 1004 } 1005 return true; 1006 } //writeURI 1007 1008 1009 // 1010 // Private methods 1011 // 1012 1013 private void prepareForSerialization(XMLSerializer ser, Node node) { 1014 ser.reset(); 1015 ser.features = features; 1016 ser.fDOMErrorHandler = fErrorHandler; 1017 ser.fNamespaces = (features & NAMESPACES) != 0; 1018 ser.fNamespacePrefixes = (features & NSDECL) != 0; 1019 ser._format.setOmitComments((features & COMMENTS)==0); 1020 ser._format.setOmitXMLDeclaration((features & XMLDECL) == 0); 1021 ser._format.setIndenting((features & FORMAT_PRETTY_PRINT) != 0); 1022 1023 if ((features & WELLFORMED) != 0) { 1024 // REVISIT: this is inefficient implementation of well-formness. Instead, we should check 1025 // well-formness as we serialize the tree 1026 Node next, root; 1027 root = node; 1028 Method versionChanged; 1029 boolean verifyNames = true; 1030 Document document =(node.getNodeType() == Node.DOCUMENT_NODE) 1031 ? (Document) node 1032 : node.getOwnerDocument(); 1033 try { 1034 versionChanged = document.getClass().getMethod("isXMLVersionChanged()", new Class[] {}); 1035 if (versionChanged != null) { 1036 verifyNames = ((Boolean)versionChanged.invoke(document, (Object[]) null)).booleanValue(); 1037 } 1038 } catch (Exception e) { 1039 //no way to test the version... 1040 //ignore the exception 1041 } 1042 if (node.getFirstChild() != null) { 1043 while (node != null) { 1044 verify(node, verifyNames, false); 1045 // Move down to first child 1046 next = node.getFirstChild(); 1047 // No child nodes, so walk tree 1048 while (next == null) { 1049 // Move to sibling if possible. 1050 next = node.getNextSibling(); 1051 if (next == null) { 1052 node = node.getParentNode(); 1053 if (root == node){ 1054 next = null; 1055 break; 1056 } 1057 next = node.getNextSibling(); 1058 } 1059 } 1060 node = next; 1061 } 1062 } 1063 else { 1064 verify(node, verifyNames, false); 1065 } 1066 } 1067 } 1068 1069 1070 private void verify (Node node, boolean verifyNames, boolean xml11Version){ 1071 1072 int type = node.getNodeType(); 1073 fLocator.fRelatedNode = node; 1074 boolean wellformed; 1075 switch (type) { 1076 case Node.DOCUMENT_NODE:{ 1077 break; 1078 } 1079 case Node.DOCUMENT_TYPE_NODE:{ 1080 break; 1081 } 1082 case Node.ELEMENT_NODE:{ 1083 if (verifyNames){ 1084 if((features & NAMESPACES) != 0){ 1085 wellformed = CoreDocumentImpl.isValidQName(node.getPrefix() , node.getLocalName(), xml11Version) ; 1086 } 1087 else{ 1088 wellformed = CoreDocumentImpl.isXMLName(node.getNodeName() , xml11Version); 1089 } 1090 if (!wellformed){ 1091 if (!wellformed){ 1092 if (fErrorHandler != null) { 1093 String msg = DOMMessageFormatter.formatMessage( 1094 DOMMessageFormatter.DOM_DOMAIN, 1095 "wf-invalid-character-in-node-name", 1096 new Object[]{"Element", node.getNodeName()}); 1097 DOMNormalizer.reportDOMError(fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_FATAL_ERROR, 1098 "wf-invalid-character-in-node-name"); 1099 } 1100 1101 } 1102 } 1103 } 1104 1105 NamedNodeMap attributes = (node.hasAttributes()) ? node.getAttributes() : null; 1106 if (attributes != null) { 1107 for (int i = 0; i < attributes.getLength(); ++i) { 1108 Attr attr = (Attr) attributes.item(i); 1109 fLocator.fRelatedNode = attr; 1110 DOMNormalizer.isAttrValueWF( fErrorHandler, fError, fLocator, 1111 attributes, attr, attr.getValue(), xml11Version); 1112 if (verifyNames) { 1113 wellformed = CoreDocumentImpl.isXMLName( attr.getNodeName(), xml11Version); 1114 if (!wellformed) { 1115 String msg = 1116 DOMMessageFormatter.formatMessage( 1117 DOMMessageFormatter.DOM_DOMAIN, 1118 "wf-invalid-character-in-node-name", 1119 new Object[] { "Attr", node.getNodeName()}); 1120 DOMNormalizer.reportDOMError( fErrorHandler, fError, fLocator, msg, DOMError.SEVERITY_FATAL_ERROR, 1121 "wf-invalid-character-in-node-name"); 1122 } 1123 } 1124 } 1125 1126 } 1127 1128 break; 1129 } 1130 1131 case Node.COMMENT_NODE: { 1132 // only verify well-formness if comments included in the tree 1133 if ((features & COMMENTS) != 0) 1134 DOMNormalizer.isCommentWF(fErrorHandler, fError, fLocator, ((Comment)node).getData(), xml11Version); 1135 break; 1136 } 1137 case Node.ENTITY_REFERENCE_NODE: { 1138 // only if entity is preserved in the tree 1139 if (verifyNames && (features & ENTITIES) != 0){ 1140 CoreDocumentImpl.isXMLName(node.getNodeName() , xml11Version); 1141 } 1142 break; 1143 1144 } 1145 case Node.CDATA_SECTION_NODE: { 1146 // verify content 1147 DOMNormalizer.isXMLCharWF(fErrorHandler, fError, fLocator, node.getNodeValue(), xml11Version); 1148 // the ]]> string will be checked during serialization 1149 break; 1150 } 1151 case Node.TEXT_NODE:{ 1152 DOMNormalizer.isXMLCharWF(fErrorHandler, fError, fLocator, node.getNodeValue(), xml11Version); 1153 break; 1154 } 1155 case Node.PROCESSING_INSTRUCTION_NODE:{ 1156 ProcessingInstruction pinode = (ProcessingInstruction)node ; 1157 String target = pinode.getTarget(); 1158 if (verifyNames) { 1159 if (xml11Version) { 1160 wellformed = XML11Char.isXML11ValidName(target); 1161 } else { 1162 wellformed = XMLChar.isValidName(target); 1163 } 1164 1165 if (!wellformed) { 1166 String msg = 1167 DOMMessageFormatter.formatMessage( 1168 DOMMessageFormatter.DOM_DOMAIN, 1169 "wf-invalid-character-in-node-name", 1170 new Object[] { "Element", node.getNodeName()}); 1171 DOMNormalizer.reportDOMError( 1172 fErrorHandler, 1173 fError, 1174 fLocator, 1175 msg, 1176 DOMError.SEVERITY_FATAL_ERROR, 1177 "wf-invalid-character-in-node-name"); 1178 } 1179 } 1180 DOMNormalizer.isXMLCharWF(fErrorHandler, fError, fLocator, pinode.getData(), xml11Version); 1181 break; 1182 } 1183 } 1184 1185 } 1186 1187 private String getPathWithoutEscapes(String origPath) { 1188 if (origPath != null && origPath.length() != 0 && origPath.indexOf('%') != -1) { 1189 // Locate the escape characters 1190 StringTokenizer tokenizer = new StringTokenizer(origPath, "%"); 1191 StringBuffer result = new StringBuffer(origPath.length()); 1192 int size = tokenizer.countTokens(); 1193 result.append(tokenizer.nextToken()); 1194 for(int i = 1; i < size; ++i) { 1195 String token = tokenizer.nextToken(); 1196 // Decode the 2 digit hexadecimal number following % in '%nn' 1197 result.append((char)Integer.valueOf(token.substring(0, 2), 16).intValue()); 1198 result.append(token.substring(2)); 1199 } 1200 return result.toString(); 1201 } 1202 return origPath; 1203 } 1204 1205 }//DOMSerializerImpl