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