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