0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */
0017:
0018: package org.apache.xml.serialize;
0019:
0020: import java.io.IOException;
0021: import java.io.OutputStream;
0022: import java.io.StringWriter;
0023: import java.io.UnsupportedEncodingException;
0024: import java.io.Writer;
0025: import java.lang.reflect.Method;
0026: import java.util.Vector;
0027:
0028: import org.apache.xerces.dom.CoreDocumentImpl;
0029: import org.apache.xerces.dom.DOMErrorImpl;
0030: import org.apache.xerces.dom.DOMLocatorImpl;
0031: import org.apache.xerces.dom.DOMMessageFormatter;
0032: import org.apache.xerces.dom.DOMNormalizer;
0033: import org.apache.xerces.dom.DOMStringListImpl;
0034: import org.apache.xerces.impl.Constants;
0035: import org.apache.xerces.impl.XMLEntityManager;
0036: import org.apache.xerces.util.DOMUtil;
0037: import org.apache.xerces.util.NamespaceSupport;
0038: import org.apache.xerces.util.SymbolTable;
0039: import org.apache.xerces.util.XML11Char;
0040: import org.apache.xerces.util.XMLChar;
0041: import org.w3c.dom.Attr;
0042: import org.w3c.dom.Comment;
0043: import org.w3c.dom.DOMConfiguration;
0044: import org.w3c.dom.DOMError;
0045: import org.w3c.dom.DOMErrorHandler;
0046: import org.w3c.dom.DOMException;
0047: import org.w3c.dom.DOMStringList;
0048: import org.w3c.dom.Document;
0049: import org.w3c.dom.DocumentFragment;
0050: import org.w3c.dom.Element;
0051: import org.w3c.dom.NamedNodeMap;
0052: import org.w3c.dom.Node;
0053: import org.w3c.dom.ProcessingInstruction;
0054: import org.w3c.dom.ls.LSException;
0055: import org.w3c.dom.ls.LSOutput;
0056: import org.w3c.dom.ls.LSSerializer;
0057: import org.w3c.dom.ls.LSSerializerFilter;
0058:
0059: /**
0060: * EXPERIMENTAL: Implemenatation of DOM Level 3 org.w3c.ls.LSSerializer by delegating serialization
0061: * calls to <CODE>XMLSerializer</CODE>.
0062: * LSSerializer provides an API for serializing (writing) a DOM document out in an
0063: * XML document. The XML data is written to an output stream.
0064: * During serialization of XML data, namespace fixup is done when possible as
0065: * defined in DOM Level 3 Core, Appendix B.
0066: *
0067: * @author Elena Litani, IBM
0068: * @author Gopal Sharma, Sun Microsystems
0069: * @author Arun Yadav, Sun Microsystems
0070: * @version $Id: DOMSerializerImpl.java 476047 2006-11-17 04:27:45Z mrglavas $
0071: *
0072: * @deprecated Replaced by org.apache.xml.serializer.dom3.LSSerializerImpl in Xerces 2.9.0.
0073: */
0074: public class DOMSerializerImpl implements LSSerializer,
0075: DOMConfiguration {
0076:
0077: // TODO: When DOM Level 3 goes to REC replace method calls using
0078: // reflection for: getXmlEncoding, getInputEncoding and getXmlEncoding
0079: // with regular static calls on the Document object.
0080:
0081: // data
0082: // serializer
0083: private XMLSerializer serializer;
0084:
0085: // XML 1.1 serializer
0086: private XML11Serializer xml11Serializer;
0087:
0088: //Recognized parameters
0089: private DOMStringList fRecognizedParameters;
0090:
0091: /** REVISIT: Currently we handle 3 different configurations, would be nice just have one configuration
0092: * that has different recognized parameters depending if it is used in Core/LS.
0093: */
0094: protected short features = 0;
0095:
0096: protected final static short NAMESPACES = 0x1 << 0;
0097: protected final static short WELLFORMED = 0x1 << 1;
0098: protected final static short ENTITIES = 0x1 << 2;
0099: protected final static short CDATA = 0x1 << 3;
0100: protected final static short SPLITCDATA = 0x1 << 4;
0101: protected final static short COMMENTS = 0x1 << 5;
0102: protected final static short DISCARDDEFAULT = 0x1 << 6;
0103: protected final static short INFOSET = 0x1 << 7;
0104: protected final static short XMLDECL = 0x1 << 8;
0105: protected final static short NSDECL = 0x1 << 9;
0106: protected final static short DOM_ELEMENT_CONTENT_WHITESPACE = 0x1 << 10;
0107: protected final static short PRETTY_PRINT = 0x1 << 11;
0108:
0109: // well-formness checking
0110: private DOMErrorHandler fErrorHandler = null;
0111: private final DOMErrorImpl fError = new DOMErrorImpl();
0112: private final DOMLocatorImpl fLocator = new DOMLocatorImpl();
0113:
0114: /**
0115: * Constructs a new LSSerializer.
0116: * The constructor turns on the namespace support in <code>XMLSerializer</code> and
0117: * initializes the following fields: fNSBinder, fLocalNSBinder, fSymbolTable,
0118: * fEmptySymbol, fXmlSymbol, fXmlnsSymbol, fNamespaceCounter, fFeatures.
0119: */
0120: public DOMSerializerImpl() {
0121: // set default features
0122: features |= NAMESPACES;
0123: features |= ENTITIES;
0124: features |= COMMENTS;
0125: features |= CDATA;
0126: features |= SPLITCDATA;
0127: features |= WELLFORMED;
0128: features |= NSDECL;
0129: features |= DOM_ELEMENT_CONTENT_WHITESPACE;
0130: features |= DISCARDDEFAULT;
0131: features |= XMLDECL;
0132:
0133: serializer = new XMLSerializer();
0134: initSerializer(serializer);
0135: }
0136:
0137: //
0138: // LSSerializer methods
0139: //
0140:
0141: public DOMConfiguration getDomConfig() {
0142: return this ;
0143: }
0144:
0145: /** DOM L3-EXPERIMENTAL:
0146: * Setter for boolean and object parameters
0147: */
0148: public void setParameter(String name, Object value)
0149: throws DOMException {
0150: if (value instanceof Boolean) {
0151: boolean state = ((Boolean) value).booleanValue();
0152: if (name.equalsIgnoreCase(Constants.DOM_INFOSET)) {
0153: if (state) {
0154: features &= ~ENTITIES;
0155: features &= ~CDATA;
0156: features |= NAMESPACES;
0157: features |= NSDECL;
0158: features |= WELLFORMED;
0159: features |= COMMENTS;
0160: }
0161: // false does not have any effect
0162: } else if (name.equalsIgnoreCase(Constants.DOM_XMLDECL)) {
0163: features = (short) (state ? features | XMLDECL
0164: : features & ~XMLDECL);
0165: } else if (name.equalsIgnoreCase(Constants.DOM_NAMESPACES)) {
0166: features = (short) (state ? features | NAMESPACES
0167: : features & ~NAMESPACES);
0168: serializer.fNamespaces = state;
0169: } else if (name.equalsIgnoreCase(Constants.DOM_SPLIT_CDATA)) {
0170: features = (short) (state ? features | SPLITCDATA
0171: : features & ~SPLITCDATA);
0172: } else if (name
0173: .equalsIgnoreCase(Constants.DOM_DISCARD_DEFAULT_CONTENT)) {
0174: features = (short) (state ? features | DISCARDDEFAULT
0175: : features & ~DISCARDDEFAULT);
0176: } else if (name.equalsIgnoreCase(Constants.DOM_WELLFORMED)) {
0177: features = (short) (state ? features | WELLFORMED
0178: : features & ~WELLFORMED);
0179: } else if (name.equalsIgnoreCase(Constants.DOM_ENTITIES)) {
0180: features = (short) (state ? features | ENTITIES
0181: : features & ~ENTITIES);
0182: } else if (name
0183: .equalsIgnoreCase(Constants.DOM_CDATA_SECTIONS)) {
0184: features = (short) (state ? features | CDATA : features
0185: & ~CDATA);
0186: } else if (name.equalsIgnoreCase(Constants.DOM_COMMENTS)) {
0187: features = (short) (state ? features | COMMENTS
0188: : features & ~COMMENTS);
0189: } else if (name
0190: .equalsIgnoreCase(Constants.DOM_FORMAT_PRETTY_PRINT)) {
0191: features = (short) (state ? features | PRETTY_PRINT
0192: : features & ~PRETTY_PRINT);
0193: } else if (name
0194: .equalsIgnoreCase(Constants.DOM_CANONICAL_FORM)
0195: || name
0196: .equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA)
0197: || name.equalsIgnoreCase(Constants.DOM_VALIDATE)
0198: || name
0199: .equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION)
0200: || name
0201: .equalsIgnoreCase(Constants.DOM_DATATYPE_NORMALIZATION)
0202: || name
0203: .equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)) {
0204: // true is not supported
0205: if (state) {
0206: String msg = DOMMessageFormatter.formatMessage(
0207: DOMMessageFormatter.DOM_DOMAIN,
0208: "FEATURE_NOT_SUPPORTED",
0209: new Object[] { name });
0210: throw new DOMException(
0211: DOMException.NOT_SUPPORTED_ERR, msg);
0212: }
0213: } else if (name
0214: .equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS)) {
0215: //namespace-declaration has effect only if namespaces is true
0216: features = (short) (state ? features | NSDECL
0217: : features & ~NSDECL);
0218: serializer.fNamespacePrefixes = state;
0219: } else if (name
0220: .equalsIgnoreCase(Constants.DOM_ELEMENT_CONTENT_WHITESPACE)
0221: || name
0222: .equalsIgnoreCase(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) {
0223: // false is not supported
0224: if (!state) {
0225: String msg = DOMMessageFormatter.formatMessage(
0226: DOMMessageFormatter.DOM_DOMAIN,
0227: "FEATURE_NOT_SUPPORTED",
0228: new Object[] { name });
0229: throw new DOMException(
0230: DOMException.NOT_SUPPORTED_ERR, msg);
0231: }
0232: } else {
0233: String msg = DOMMessageFormatter.formatMessage(
0234: DOMMessageFormatter.DOM_DOMAIN,
0235: "FEATURE_NOT_FOUND", new Object[] { name });
0236: throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
0237: msg);
0238: }
0239: } else if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER)) {
0240: if (value == null || value instanceof DOMErrorHandler) {
0241: fErrorHandler = (DOMErrorHandler) value;
0242: } else {
0243: String msg = DOMMessageFormatter.formatMessage(
0244: DOMMessageFormatter.DOM_DOMAIN,
0245: "TYPE_MISMATCH_ERR", new Object[] { name });
0246: throw new DOMException(DOMException.TYPE_MISMATCH_ERR,
0247: msg);
0248: }
0249: } else if (name
0250: .equalsIgnoreCase(Constants.DOM_RESOURCE_RESOLVER)
0251: || name.equalsIgnoreCase(Constants.DOM_SCHEMA_LOCATION)
0252: || name.equalsIgnoreCase(Constants.DOM_SCHEMA_TYPE)
0253: && value != null) {
0254: String msg = DOMMessageFormatter.formatMessage(
0255: DOMMessageFormatter.DOM_DOMAIN,
0256: "FEATURE_NOT_SUPPORTED", new Object[] { name });
0257: throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
0258: } else {
0259: String msg = DOMMessageFormatter.formatMessage(
0260: DOMMessageFormatter.DOM_DOMAIN,
0261: "FEATURE_NOT_FOUND", new Object[] { name });
0262: throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
0263: }
0264: }
0265:
0266: /** DOM L3-EXPERIMENTAL:
0267: * Check if parameter can be set
0268: */
0269: public boolean canSetParameter(String name, Object state) {
0270: if (state == null) {
0271: return true;
0272: }
0273:
0274: if (state instanceof Boolean) {
0275: boolean value = ((Boolean) state).booleanValue();
0276: if (name.equalsIgnoreCase(Constants.DOM_NAMESPACES)
0277: || name.equalsIgnoreCase(Constants.DOM_SPLIT_CDATA)
0278: || name
0279: .equalsIgnoreCase(Constants.DOM_DISCARD_DEFAULT_CONTENT)
0280: || name.equalsIgnoreCase(Constants.DOM_XMLDECL)
0281: || name.equalsIgnoreCase(Constants.DOM_WELLFORMED)
0282: || name.equalsIgnoreCase(Constants.DOM_INFOSET)
0283: || name.equalsIgnoreCase(Constants.DOM_ENTITIES)
0284: || name
0285: .equalsIgnoreCase(Constants.DOM_CDATA_SECTIONS)
0286: || name.equalsIgnoreCase(Constants.DOM_COMMENTS)
0287: || name
0288: .equalsIgnoreCase(Constants.DOM_FORMAT_PRETTY_PRINT)
0289: || name
0290: .equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS)) {
0291: // both values supported
0292: return true;
0293: } else if (name
0294: .equalsIgnoreCase(Constants.DOM_CANONICAL_FORM)
0295: || name
0296: .equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA)
0297: || name.equalsIgnoreCase(Constants.DOM_VALIDATE)
0298: || name
0299: .equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION)
0300: || name
0301: .equalsIgnoreCase(Constants.DOM_DATATYPE_NORMALIZATION)
0302: || name
0303: .equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)) {
0304: // true is not supported
0305: return !value;
0306: } else if (name
0307: .equalsIgnoreCase(Constants.DOM_ELEMENT_CONTENT_WHITESPACE)
0308: || name
0309: .equalsIgnoreCase(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) {
0310: // false is not supported
0311: return value;
0312: }
0313: } else if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER)
0314: && state == null || state instanceof DOMErrorHandler) {
0315: return true;
0316: }
0317: return false;
0318: }
0319:
0320: /**
0321: * DOM Level 3 Core CR - Experimental.
0322: *
0323: * The list of the parameters supported by this
0324: * <code>DOMConfiguration</code> object and for which at least one value
0325: * can be set by the application. Note that this list can also contain
0326: * parameter names defined outside this specification.
0327: */
0328: public DOMStringList getParameterNames() {
0329:
0330: if (fRecognizedParameters == null) {
0331: Vector parameters = new Vector();
0332:
0333: //Add DOM recognized parameters
0334: //REVISIT: Would have been nice to have a list of
0335: //recognized parameters.
0336: parameters.add(Constants.DOM_NAMESPACES);
0337: parameters.add(Constants.DOM_SPLIT_CDATA);
0338: parameters.add(Constants.DOM_DISCARD_DEFAULT_CONTENT);
0339: parameters.add(Constants.DOM_XMLDECL);
0340: parameters.add(Constants.DOM_CANONICAL_FORM);
0341: parameters.add(Constants.DOM_VALIDATE_IF_SCHEMA);
0342: parameters.add(Constants.DOM_VALIDATE);
0343: parameters.add(Constants.DOM_CHECK_CHAR_NORMALIZATION);
0344: parameters.add(Constants.DOM_DATATYPE_NORMALIZATION);
0345: parameters.add(Constants.DOM_FORMAT_PRETTY_PRINT);
0346: parameters.add(Constants.DOM_NORMALIZE_CHARACTERS);
0347: parameters.add(Constants.DOM_WELLFORMED);
0348: parameters.add(Constants.DOM_INFOSET);
0349: parameters.add(Constants.DOM_NAMESPACE_DECLARATIONS);
0350: parameters.add(Constants.DOM_ELEMENT_CONTENT_WHITESPACE);
0351: parameters.add(Constants.DOM_ENTITIES);
0352: parameters.add(Constants.DOM_CDATA_SECTIONS);
0353: parameters.add(Constants.DOM_COMMENTS);
0354: parameters
0355: .add(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS);
0356: parameters.add(Constants.DOM_ERROR_HANDLER);
0357: //parameters.add(Constants.DOM_SCHEMA_LOCATION);
0358: //parameters.add(Constants.DOM_SCHEMA_TYPE);
0359:
0360: //Add recognized xerces features and properties
0361:
0362: fRecognizedParameters = new DOMStringListImpl(parameters);
0363:
0364: }
0365:
0366: return fRecognizedParameters;
0367: }
0368:
0369: /** DOM L3-EXPERIMENTAL:
0370: * Getter for boolean and object parameters
0371: */
0372: public Object getParameter(String name) throws DOMException {
0373: if (name.equalsIgnoreCase(Constants.DOM_COMMENTS)) {
0374: return ((features & COMMENTS) != 0) ? Boolean.TRUE
0375: : Boolean.FALSE;
0376: } else if (name.equalsIgnoreCase(Constants.DOM_NAMESPACES)) {
0377: return (features & NAMESPACES) != 0 ? Boolean.TRUE
0378: : Boolean.FALSE;
0379: } else if (name.equalsIgnoreCase(Constants.DOM_XMLDECL)) {
0380: return (features & XMLDECL) != 0 ? Boolean.TRUE
0381: : Boolean.FALSE;
0382: } else if (name.equalsIgnoreCase(Constants.DOM_CDATA_SECTIONS)) {
0383: return (features & CDATA) != 0 ? Boolean.TRUE
0384: : Boolean.FALSE;
0385: } else if (name.equalsIgnoreCase(Constants.DOM_ENTITIES)) {
0386: return (features & ENTITIES) != 0 ? Boolean.TRUE
0387: : Boolean.FALSE;
0388: } else if (name.equalsIgnoreCase(Constants.DOM_SPLIT_CDATA)) {
0389: return (features & SPLITCDATA) != 0 ? Boolean.TRUE
0390: : Boolean.FALSE;
0391: } else if (name.equalsIgnoreCase(Constants.DOM_WELLFORMED)) {
0392: return (features & WELLFORMED) != 0 ? Boolean.TRUE
0393: : Boolean.FALSE;
0394: } else if (name
0395: .equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS)) {
0396: return (features & NSDECL) != 0 ? Boolean.TRUE
0397: : Boolean.FALSE;
0398: } else if (name
0399: .equalsIgnoreCase(Constants.DOM_ELEMENT_CONTENT_WHITESPACE)
0400: || name
0401: .equalsIgnoreCase(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) {
0402: return Boolean.TRUE;
0403: } else if (name
0404: .equalsIgnoreCase(Constants.DOM_DISCARD_DEFAULT_CONTENT)) {
0405: return ((features & DISCARDDEFAULT) != 0) ? Boolean.TRUE
0406: : Boolean.FALSE;
0407: } else if (name
0408: .equalsIgnoreCase(Constants.DOM_FORMAT_PRETTY_PRINT)) {
0409: return ((features & PRETTY_PRINT) != 0) ? Boolean.TRUE
0410: : Boolean.FALSE;
0411: } else if (name.equalsIgnoreCase(Constants.DOM_INFOSET)) {
0412: if ((features & ENTITIES) == 0 && (features & CDATA) == 0
0413: && (features & NAMESPACES) != 0
0414: && (features & NSDECL) != 0
0415: && (features & WELLFORMED) != 0
0416: && (features & COMMENTS) != 0) {
0417: return Boolean.TRUE;
0418: }
0419: return Boolean.FALSE;
0420: } else if (name
0421: .equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)
0422: || name.equalsIgnoreCase(Constants.DOM_CANONICAL_FORM)
0423: || name
0424: .equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA)
0425: || name
0426: .equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION)
0427: || name.equalsIgnoreCase(Constants.DOM_VALIDATE)
0428: || name
0429: .equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA)
0430: || name
0431: .equalsIgnoreCase(Constants.DOM_DATATYPE_NORMALIZATION)) {
0432: return Boolean.FALSE;
0433: } else if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER)) {
0434: return fErrorHandler;
0435: } else if (name
0436: .equalsIgnoreCase(Constants.DOM_RESOURCE_RESOLVER)
0437: || name.equalsIgnoreCase(Constants.DOM_SCHEMA_LOCATION)
0438: || name.equalsIgnoreCase(Constants.DOM_SCHEMA_TYPE)) {
0439: String msg = DOMMessageFormatter.formatMessage(
0440: DOMMessageFormatter.DOM_DOMAIN,
0441: "FEATURE_NOT_SUPPORTED", new Object[] { name });
0442: throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
0443: } else {
0444: String msg = DOMMessageFormatter.formatMessage(
0445: DOMMessageFormatter.DOM_DOMAIN,
0446: "FEATURE_NOT_FOUND", new Object[] { name });
0447: throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
0448: }
0449: }
0450:
0451: /**
0452: * DOM L3 EXPERIMENTAL:
0453: * Serialize the specified node as described above in the description of
0454: * <code>LSSerializer</code>. The result of serializing the node is
0455: * returned as a string. Writing a Document or Entity node produces a
0456: * serialized form that is well formed XML. Writing other node types
0457: * produces a fragment of text in a form that is not fully defined by
0458: * this document, but that should be useful to a human for debugging or
0459: * diagnostic purposes.
0460: * @param wnode The node to be written.
0461: * @return Returns the serialized data
0462: * @exception DOMException
0463: * DOMSTRING_SIZE_ERR: The resulting string is too long to fit in a
0464: * <code>DOMString</code>.
0465: * @exception LSException
0466: * SERIALIZE_ERR: Unable to serialize the node. DOM applications should
0467: * attach a <code>DOMErrorHandler</code> using the parameter
0468: * "<i>error-handler</i>" to get details on error.
0469: */
0470: public String writeToString(Node wnode) throws DOMException,
0471: LSException {
0472: // determine which serializer to use:
0473: XMLSerializer ser = null;
0474: String ver = _getXmlVersion(wnode);
0475: if (ver != null && ver.equals("1.1")) {
0476: if (xml11Serializer == null) {
0477: xml11Serializer = new XML11Serializer();
0478: initSerializer(xml11Serializer);
0479: }
0480: // copy setting from "main" serializer to XML 1.1 serializer
0481: copySettings(serializer, xml11Serializer);
0482: ser = xml11Serializer;
0483: } else {
0484: ser = serializer;
0485: }
0486:
0487: StringWriter destination = new StringWriter();
0488: try {
0489: prepareForSerialization(ser, wnode);
0490: ser._format.setEncoding("UTF-16");
0491: ser.setOutputCharStream(destination);
0492: if (wnode.getNodeType() == Node.DOCUMENT_NODE) {
0493: ser.serialize((Document) wnode);
0494: } else if (wnode.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE) {
0495: ser.serialize((DocumentFragment) wnode);
0496: } else if (wnode.getNodeType() == Node.ELEMENT_NODE) {
0497: ser.serialize((Element) wnode);
0498: } else {
0499: String msg = DOMMessageFormatter.formatMessage(
0500: DOMMessageFormatter.SERIALIZER_DOMAIN,
0501: "unable-to-serialize-node", null);
0502: if (ser.fDOMErrorHandler != null) {
0503: DOMErrorImpl error = new DOMErrorImpl();
0504: error.fType = "unable-to-serialize-node";
0505: error.fMessage = msg;
0506: error.fSeverity = DOMError.SEVERITY_FATAL_ERROR;
0507: ser.fDOMErrorHandler.handleError(error);
0508: }
0509: throw new LSException(LSException.SERIALIZE_ERR, msg);
0510: }
0511: } catch (LSException lse) {
0512: // Rethrow LSException.
0513: throw lse;
0514: } catch (RuntimeException e) {
0515: if (e == DOMNormalizer.abort) {
0516: // stopped at user request
0517: return null;
0518: }
0519: throw (LSException) DOMUtil.createLSException(
0520: LSException.SERIALIZE_ERR, e).fillInStackTrace();
0521: } catch (IOException ioe) {
0522: // REVISIT: A generic IOException doesn't provide enough information
0523: // to determine that the serialized document is too large to fit
0524: // into a string. This could have thrown for some other reason. -- mrglavas
0525: String msg = DOMMessageFormatter.formatMessage(
0526: DOMMessageFormatter.DOM_DOMAIN, "STRING_TOO_LONG",
0527: new Object[] { ioe.getMessage() });
0528: throw new DOMException(DOMException.DOMSTRING_SIZE_ERR, msg);
0529: } finally {
0530: ser.clearDocumentState();
0531: }
0532: return destination.toString();
0533: }
0534:
0535: /**
0536: * DOM L3 EXPERIMENTAL:
0537: * The end-of-line sequence of characters to be used in the XML being
0538: * written out. The only permitted values are these:
0539: * <dl>
0540: * <dt><code>null</code></dt>
0541: * <dd>
0542: * Use a default end-of-line sequence. DOM implementations should choose
0543: * the default to match the usual convention for text files in the
0544: * environment being used. Implementations must choose a default
0545: * sequence that matches one of those allowed by 2.11 "End-of-Line
0546: * Handling". </dd>
0547: * <dt>CR</dt>
0548: * <dd>The carriage-return character (#xD).</dd>
0549: * <dt>CR-LF</dt>
0550: * <dd> The
0551: * carriage-return and line-feed characters (#xD #xA). </dd>
0552: * <dt>LF</dt>
0553: * <dd> The line-feed
0554: * character (#xA). </dd>
0555: * </dl>
0556: * <br>The default value for this attribute is <code>null</code>.
0557: */
0558: public void setNewLine(String newLine) {
0559: serializer._format.setLineSeparator(newLine);
0560: }
0561:
0562: /**
0563: * DOM L3 EXPERIMENTAL:
0564: * The end-of-line sequence of characters to be used in the XML being
0565: * written out. The only permitted values are these:
0566: * <dl>
0567: * <dt><code>null</code></dt>
0568: * <dd>
0569: * Use a default end-of-line sequence. DOM implementations should choose
0570: * the default to match the usual convention for text files in the
0571: * environment being used. Implementations must choose a default
0572: * sequence that matches one of those allowed by 2.11 "End-of-Line
0573: * Handling". </dd>
0574: * <dt>CR</dt>
0575: * <dd>The carriage-return character (#xD).</dd>
0576: * <dt>CR-LF</dt>
0577: * <dd> The
0578: * carriage-return and line-feed characters (#xD #xA). </dd>
0579: * <dt>LF</dt>
0580: * <dd> The line-feed
0581: * character (#xA). </dd>
0582: * </dl>
0583: * <br>The default value for this attribute is <code>null</code>.
0584: */
0585: public String getNewLine() {
0586: return serializer._format.getLineSeparator();
0587: }
0588:
0589: /**
0590: * When the application provides a filter, the serializer will call out
0591: * to the filter before serializing each Node. Attribute nodes are never
0592: * passed to the filter. The filter implementation can choose to remove
0593: * the node from the stream or to terminate the serialization early.
0594: */
0595: public LSSerializerFilter getFilter() {
0596: return serializer.fDOMFilter;
0597: }
0598:
0599: /**
0600: * When the application provides a filter, the serializer will call out
0601: * to the filter before serializing each Node. Attribute nodes are never
0602: * passed to the filter. The filter implementation can choose to remove
0603: * the node from the stream or to terminate the serialization early.
0604: */
0605: public void setFilter(LSSerializerFilter filter) {
0606: serializer.fDOMFilter = filter;
0607: }
0608:
0609: // this initializes a newly-created serializer
0610: private void initSerializer(XMLSerializer ser) {
0611: ser.fNSBinder = new NamespaceSupport();
0612: ser.fLocalNSBinder = new NamespaceSupport();
0613: ser.fSymbolTable = new SymbolTable();
0614: }
0615:
0616: // copies all settings that could have been modified
0617: // by calls to LSSerializer methods from one serializer to another.
0618: // IMPORTANT: if new methods are implemented or more settings of
0619: // the serializer are made alterable, this must be
0620: // reflected in this method!
0621: private void copySettings(XMLSerializer src, XMLSerializer dest) {
0622: dest.fDOMErrorHandler = fErrorHandler;
0623: dest._format.setEncoding(src._format.getEncoding());
0624: dest._format.setLineSeparator(src._format.getLineSeparator());
0625: dest.fDOMFilter = src.fDOMFilter;
0626: }//copysettings
0627:
0628: /**
0629: * Serialize the specified node as described above in the general
0630: * description of the <code>LSSerializer</code> interface. The output
0631: * is written to the supplied <code>LSOutput</code>.
0632: * <br> When writing to a <code>LSOutput</code>, the encoding is found by
0633: * looking at the encoding information that is reachable through the
0634: * <code>LSOutput</code> and the item to be written (or its owner
0635: * document) in this order:
0636: * <ol>
0637: * <li> <code>LSOutput.encoding</code>,
0638: * </li>
0639: * <li>
0640: * <code>Document.actualEncoding</code>,
0641: * </li>
0642: * <li>
0643: * <code>Document.xmlEncoding</code>.
0644: * </li>
0645: * </ol>
0646: * <br> If no encoding is reachable through the above properties, a
0647: * default encoding of "UTF-8" will be used.
0648: * <br> If the specified encoding is not supported an
0649: * "unsupported-encoding" error is raised.
0650: * <br> If no output is specified in the <code>LSOutput</code>, a
0651: * "no-output-specified" error is raised.
0652: * @param node The node to serialize.
0653: * @param destination The destination for the serialized DOM.
0654: * @return Returns <code>true</code> if <code>node</code> was
0655: * successfully serialized and <code>false</code> in case the node
0656: * couldn't be serialized.
0657: */
0658: public boolean write(Node node, LSOutput destination)
0659: throws LSException {
0660:
0661: if (node == null)
0662: return false;
0663:
0664: XMLSerializer ser = null;
0665: String ver = _getXmlVersion(node);
0666: //determine which serializer to use:
0667: if (ver != null && ver.equals("1.1")) {
0668: if (xml11Serializer == null) {
0669: xml11Serializer = new XML11Serializer();
0670: initSerializer(xml11Serializer);
0671: }
0672: //copy setting from "main" serializer to XML 1.1 serializer
0673: copySettings(serializer, xml11Serializer);
0674: ser = xml11Serializer;
0675: } else {
0676: ser = serializer;
0677: }
0678:
0679: String encoding = null;
0680: if ((encoding = destination.getEncoding()) == null) {
0681: encoding = _getInputEncoding(node);
0682: if (encoding == null) {
0683: encoding = _getXmlEncoding(node);
0684: if (encoding == null) {
0685: encoding = "UTF-8";
0686: }
0687: }
0688: }
0689: try {
0690: prepareForSerialization(ser, node);
0691: ser._format.setEncoding(encoding);
0692: OutputStream outputStream = destination.getByteStream();
0693: Writer writer = destination.getCharacterStream();
0694: String uri = destination.getSystemId();
0695: if (writer == null) {
0696: if (outputStream == null) {
0697: if (uri == null) {
0698: String msg = DOMMessageFormatter.formatMessage(
0699: DOMMessageFormatter.SERIALIZER_DOMAIN,
0700: "no-output-specified", null);
0701: if (ser.fDOMErrorHandler != null) {
0702: DOMErrorImpl error = new DOMErrorImpl();
0703: error.fType = "no-output-specified";
0704: error.fMessage = msg;
0705: error.fSeverity = DOMError.SEVERITY_FATAL_ERROR;
0706: ser.fDOMErrorHandler.handleError(error);
0707: }
0708: throw new LSException(
0709: LSException.SERIALIZE_ERR, msg);
0710: } else {
0711: ser.setOutputByteStream(XMLEntityManager
0712: .createOutputStream(uri));
0713: }
0714: } else {
0715: // byte stream was specified
0716: ser.setOutputByteStream(outputStream);
0717: }
0718: } else {
0719: // character stream is specified
0720: ser.setOutputCharStream(writer);
0721: }
0722:
0723: if (node.getNodeType() == Node.DOCUMENT_NODE)
0724: ser.serialize((Document) node);
0725: else if (node.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE)
0726: ser.serialize((DocumentFragment) node);
0727: else if (node.getNodeType() == Node.ELEMENT_NODE)
0728: ser.serialize((Element) node);
0729: else
0730: return false;
0731: } catch (UnsupportedEncodingException ue) {
0732: if (ser.fDOMErrorHandler != null) {
0733: DOMErrorImpl error = new DOMErrorImpl();
0734: error.fException = ue;
0735: error.fType = "unsupported-encoding";
0736: error.fMessage = ue.getMessage();
0737: error.fSeverity = DOMError.SEVERITY_FATAL_ERROR;
0738: ser.fDOMErrorHandler.handleError(error);
0739: }
0740: throw new LSException(LSException.SERIALIZE_ERR,
0741: DOMMessageFormatter.formatMessage(
0742: DOMMessageFormatter.SERIALIZER_DOMAIN,
0743: "unsupported-encoding", null));
0744: //return false;
0745: } catch (LSException lse) {
0746: // Rethrow LSException.
0747: throw lse;
0748: } catch (RuntimeException e) {
0749: if (e == DOMNormalizer.abort) {
0750: // stopped at user request
0751: return false;
0752: }
0753: throw (LSException) DOMUtil.createLSException(
0754: LSException.SERIALIZE_ERR, e).fillInStackTrace();
0755: } catch (Exception e) {
0756: if (ser.fDOMErrorHandler != null) {
0757: DOMErrorImpl error = new DOMErrorImpl();
0758: error.fException = e;
0759: error.fMessage = e.getMessage();
0760: error.fSeverity = DOMError.SEVERITY_ERROR;
0761: ser.fDOMErrorHandler.handleError(error);
0762:
0763: }
0764: throw (LSException) DOMUtil.createLSException(
0765: LSException.SERIALIZE_ERR, e).fillInStackTrace();
0766: } finally {
0767: ser.clearDocumentState();
0768: }
0769: return true;
0770:
0771: } //write
0772:
0773: /**
0774: * Serialize the specified node as described above in the general
0775: * description of the <code>LSSerializer</code> interface. The output
0776: * is written to the supplied URI.
0777: * <br> When writing to a URI, the encoding is found by looking at the
0778: * encoding information that is reachable through the item to be written
0779: * (or its owner document) in this order:
0780: * <ol>
0781: * <li>
0782: * <code>Document.inputEncoding</code>,
0783: * </li>
0784: * <li>
0785: * <code>Document.xmlEncoding</code>.
0786: * </li>
0787: * </ol>
0788: * <br> If no encoding is reachable through the above properties, a
0789: * default encoding of "UTF-8" will be used.
0790: * <br> If the specified encoding is not supported an
0791: * "unsupported-encoding" error is raised.
0792: * @param node The node to serialize.
0793: * @param URI The URI to write to.
0794: * @return Returns <code>true</code> if <code>node</code> was
0795: * successfully serialized and <code>false</code> in case the node
0796: * couldn't be serialized.
0797: */
0798: public boolean writeToURI(Node node, String URI) throws LSException {
0799: if (node == null) {
0800: return false;
0801: }
0802:
0803: XMLSerializer ser = null;
0804: String ver = _getXmlVersion(node);
0805:
0806: if (ver != null && ver.equals("1.1")) {
0807: if (xml11Serializer == null) {
0808: xml11Serializer = new XML11Serializer();
0809: initSerializer(xml11Serializer);
0810: }
0811: // copy setting from "main" serializer to XML 1.1 serializer
0812: copySettings(serializer, xml11Serializer);
0813: ser = xml11Serializer;
0814: } else {
0815: ser = serializer;
0816: }
0817:
0818: String encoding = _getInputEncoding(node);
0819: if (encoding == null) {
0820: encoding = _getXmlEncoding(node);
0821: if (encoding == null) {
0822: encoding = "UTF-8";
0823: }
0824: }
0825:
0826: try {
0827: prepareForSerialization(ser, node);
0828: ser._format.setEncoding(encoding);
0829: ser.setOutputByteStream(XMLEntityManager
0830: .createOutputStream(URI));
0831:
0832: if (node.getNodeType() == Node.DOCUMENT_NODE)
0833: ser.serialize((Document) node);
0834: else if (node.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE)
0835: ser.serialize((DocumentFragment) node);
0836: else if (node.getNodeType() == Node.ELEMENT_NODE)
0837: ser.serialize((Element) node);
0838: else
0839: return false;
0840: } catch (LSException lse) {
0841: // Rethrow LSException.
0842: throw lse;
0843: } catch (RuntimeException e) {
0844: if (e == DOMNormalizer.abort) {
0845: // stopped at user request
0846: return false;
0847: }
0848: throw (LSException) DOMUtil.createLSException(
0849: LSException.SERIALIZE_ERR, e).fillInStackTrace();
0850: } catch (Exception e) {
0851: if (ser.fDOMErrorHandler != null) {
0852: DOMErrorImpl error = new DOMErrorImpl();
0853: error.fException = e;
0854: error.fMessage = e.getMessage();
0855: error.fSeverity = DOMError.SEVERITY_ERROR;
0856: ser.fDOMErrorHandler.handleError(error);
0857: }
0858: throw (LSException) DOMUtil.createLSException(
0859: LSException.SERIALIZE_ERR, e).fillInStackTrace();
0860: } finally {
0861: ser.clearDocumentState();
0862: }
0863: return true;
0864: } //writeURI
0865:
0866: //
0867: // Private methods
0868: //
0869:
0870: private void prepareForSerialization(XMLSerializer ser, Node node) {
0871: ser.reset();
0872: ser.features = features;
0873: ser.fDOMErrorHandler = fErrorHandler;
0874: ser.fNamespaces = (features & NAMESPACES) != 0;
0875: ser.fNamespacePrefixes = (features & NSDECL) != 0;
0876: ser._format.setIndenting((features & PRETTY_PRINT) != 0);
0877: ser._format.setOmitComments((features & COMMENTS) == 0);
0878: ser._format.setOmitXMLDeclaration((features & XMLDECL) == 0);
0879:
0880: if ((features & WELLFORMED) != 0) {
0881: // REVISIT: this is inefficient implementation of well-formness. Instead, we should check
0882: // well-formness as we serialize the tree
0883: Node next, root;
0884: root = node;
0885: Method versionChanged;
0886: boolean verifyNames = true;
0887: Document document = (node.getNodeType() == Node.DOCUMENT_NODE) ? (Document) node
0888: : node.getOwnerDocument();
0889: try {
0890: versionChanged = document.getClass().getMethod(
0891: "isXMLVersionChanged()", new Class[] {});
0892: if (versionChanged != null) {
0893: verifyNames = ((Boolean) versionChanged.invoke(
0894: document, (Object[]) null)).booleanValue();
0895: }
0896: } catch (Exception e) {
0897: //no way to test the version...
0898: //ignore the exception
0899: }
0900: if (node.getFirstChild() != null) {
0901: while (node != null) {
0902: verify(node, verifyNames, false);
0903: // Move down to first child
0904: next = node.getFirstChild();
0905: // No child nodes, so walk tree
0906: while (next == null) {
0907: // Move to sibling if possible.
0908: next = node.getNextSibling();
0909: if (next == null) {
0910: node = node.getParentNode();
0911: if (root == node) {
0912: next = null;
0913: break;
0914: }
0915: next = node.getNextSibling();
0916: }
0917: }
0918: node = next;
0919: }
0920: } else {
0921: verify(node, verifyNames, false);
0922: }
0923: }
0924: }
0925:
0926: private void verify(Node node, boolean verifyNames,
0927: boolean xml11Version) {
0928:
0929: int type = node.getNodeType();
0930: fLocator.fRelatedNode = node;
0931: boolean wellformed;
0932: switch (type) {
0933: case Node.DOCUMENT_NODE: {
0934: break;
0935: }
0936: case Node.DOCUMENT_TYPE_NODE: {
0937: break;
0938: }
0939: case Node.ELEMENT_NODE: {
0940: if (verifyNames) {
0941: if ((features & NAMESPACES) != 0) {
0942: wellformed = CoreDocumentImpl.isValidQName(node
0943: .getPrefix(), node.getLocalName(),
0944: xml11Version);
0945: } else {
0946: wellformed = CoreDocumentImpl.isXMLName(node
0947: .getNodeName(), xml11Version);
0948: }
0949: if (!wellformed) {
0950: if (!wellformed) {
0951: if (fErrorHandler != null) {
0952: String msg = DOMMessageFormatter
0953: .formatMessage(
0954: DOMMessageFormatter.DOM_DOMAIN,
0955: "wf-invalid-character-in-node-name",
0956: new Object[] { "Element",
0957: node.getNodeName() });
0958: DOMNormalizer
0959: .reportDOMError(
0960: fErrorHandler,
0961: fError,
0962: fLocator,
0963: msg,
0964: DOMError.SEVERITY_FATAL_ERROR,
0965: "wf-invalid-character-in-node-name");
0966: }
0967:
0968: }
0969: }
0970: }
0971:
0972: NamedNodeMap attributes = (node.hasAttributes()) ? node
0973: .getAttributes() : null;
0974: if (attributes != null) {
0975: for (int i = 0; i < attributes.getLength(); ++i) {
0976: Attr attr = (Attr) attributes.item(i);
0977: fLocator.fRelatedNode = attr;
0978: DOMNormalizer.isAttrValueWF(fErrorHandler, fError,
0979: fLocator, attributes, attr,
0980: attr.getValue(), xml11Version);
0981: if (verifyNames) {
0982: wellformed = CoreDocumentImpl.isXMLName(attr
0983: .getNodeName(), xml11Version);
0984: if (!wellformed) {
0985: String msg = DOMMessageFormatter
0986: .formatMessage(
0987: DOMMessageFormatter.DOM_DOMAIN,
0988: "wf-invalid-character-in-node-name",
0989: new Object[] { "Attr",
0990: node.getNodeName() });
0991: DOMNormalizer
0992: .reportDOMError(
0993: fErrorHandler,
0994: fError,
0995: fLocator,
0996: msg,
0997: DOMError.SEVERITY_FATAL_ERROR,
0998: "wf-invalid-character-in-node-name");
0999: }
1000: }
1001: }
1002:
1003: }
1004:
1005: break;
1006: }
1007:
1008: case Node.COMMENT_NODE: {
1009: // only verify well-formness if comments included in the tree
1010: if ((features & COMMENTS) != 0)
1011: DOMNormalizer.isCommentWF(fErrorHandler, fError,
1012: fLocator, ((Comment) node).getData(),
1013: xml11Version);
1014: break;
1015: }
1016: case Node.ENTITY_REFERENCE_NODE: {
1017: // only if entity is preserved in the tree
1018: if (verifyNames && (features & ENTITIES) != 0) {
1019: CoreDocumentImpl.isXMLName(node.getNodeName(),
1020: xml11Version);
1021: }
1022: break;
1023:
1024: }
1025: case Node.CDATA_SECTION_NODE: {
1026: // verify content
1027: DOMNormalizer.isXMLCharWF(fErrorHandler, fError, fLocator,
1028: node.getNodeValue(), xml11Version);
1029: // the ]]> string will be checked during serialization
1030: break;
1031: }
1032: case Node.TEXT_NODE: {
1033: DOMNormalizer.isXMLCharWF(fErrorHandler, fError, fLocator,
1034: node.getNodeValue(), xml11Version);
1035: break;
1036: }
1037: case Node.PROCESSING_INSTRUCTION_NODE: {
1038: ProcessingInstruction pinode = (ProcessingInstruction) node;
1039: String target = pinode.getTarget();
1040: if (verifyNames) {
1041: if (xml11Version) {
1042: wellformed = XML11Char.isXML11ValidName(target);
1043: } else {
1044: wellformed = XMLChar.isValidName(target);
1045: }
1046:
1047: if (!wellformed) {
1048: String msg = DOMMessageFormatter.formatMessage(
1049: DOMMessageFormatter.DOM_DOMAIN,
1050: "wf-invalid-character-in-node-name",
1051: new Object[] { "Element",
1052: node.getNodeName() });
1053: DOMNormalizer.reportDOMError(fErrorHandler, fError,
1054: fLocator, msg,
1055: DOMError.SEVERITY_FATAL_ERROR,
1056: "wf-invalid-character-in-node-name");
1057: }
1058: }
1059: DOMNormalizer.isXMLCharWF(fErrorHandler, fError, fLocator,
1060: pinode.getData(), xml11Version);
1061: break;
1062: }
1063: }
1064:
1065: }
1066:
1067: private String _getXmlVersion(Node node) {
1068: Document doc = (node.getNodeType() == Node.DOCUMENT_NODE) ? (Document) node
1069: : node.getOwnerDocument();
1070: if (doc != null && DocumentMethods.fgDocumentMethodsAvailable) {
1071: try {
1072: return (String) DocumentMethods.fgDocumentGetXmlVersionMethod
1073: .invoke(doc, (Object[]) null);
1074: }
1075: // The VM ran out of memory or there was some other serious problem. Re-throw.
1076: catch (VirtualMachineError vme) {
1077: throw vme;
1078: }
1079: // ThreadDeath should always be re-thrown
1080: catch (ThreadDeath td) {
1081: throw td;
1082: }
1083: // Ignore all other exceptions and errors
1084: catch (Throwable t) {
1085: }
1086: }
1087: return null;
1088: }
1089:
1090: private String _getInputEncoding(Node node) {
1091: Document doc = (node.getNodeType() == Node.DOCUMENT_NODE) ? (Document) node
1092: : node.getOwnerDocument();
1093: if (doc != null && DocumentMethods.fgDocumentMethodsAvailable) {
1094: try {
1095: return (String) DocumentMethods.fgDocumentGetInputEncodingMethod
1096: .invoke(doc, (Object[]) null);
1097: }
1098: // The VM ran out of memory or there was some other serious problem. Re-throw.
1099: catch (VirtualMachineError vme) {
1100: throw vme;
1101: }
1102: // ThreadDeath should always be re-thrown
1103: catch (ThreadDeath td) {
1104: throw td;
1105: }
1106: // Ignore all other exceptions and errors
1107: catch (Throwable t) {
1108: }
1109: }
1110: return null;
1111: }
1112:
1113: private String _getXmlEncoding(Node node) {
1114: Document doc = (node.getNodeType() == Node.DOCUMENT_NODE) ? (Document) node
1115: : node.getOwnerDocument();
1116: if (doc != null && DocumentMethods.fgDocumentMethodsAvailable) {
1117: try {
1118: return (String) DocumentMethods.fgDocumentGetXmlEncodingMethod
1119: .invoke(doc, (Object[]) null);
1120: }
1121: // The VM ran out of memory or there was some other serious problem. Re-throw.
1122: catch (VirtualMachineError vme) {
1123: throw vme;
1124: }
1125: // ThreadDeath should always be re-thrown
1126: catch (ThreadDeath td) {
1127: throw td;
1128: }
1129: // Ignore all other exceptions and errors
1130: catch (Throwable t) {
1131: }
1132: }
1133: return null;
1134: }
1135:
1136: /**
1137: * Holder of DOM Level 3 methods from org.w3c.dom.Document.
1138: */
1139: static class DocumentMethods {
1140:
1141: // Method: org.w3c.dom.Document.getXmlVersion()
1142: private static java.lang.reflect.Method fgDocumentGetXmlVersionMethod = null;
1143:
1144: // Method: org.w3c.dom.Document.getInputEncoding()
1145: private static java.lang.reflect.Method fgDocumentGetInputEncodingMethod = null;
1146:
1147: // Method: org.w3c.dom.Document.getXmlEncoding()
1148: private static java.lang.reflect.Method fgDocumentGetXmlEncodingMethod = null;
1149:
1150: // Flag indicating whether or not Document methods are available.
1151: private static boolean fgDocumentMethodsAvailable = false;
1152:
1153: private DocumentMethods() {
1154: }
1155:
1156: // Attempt to get methods for org.w3c.dom.Document on class initialization.
1157: static {
1158: try {
1159: fgDocumentGetXmlVersionMethod = Document.class
1160: .getMethod("getXmlVersion", new Class[] {});
1161: fgDocumentGetInputEncodingMethod = Document.class
1162: .getMethod("getInputEncoding", new Class[] {});
1163: fgDocumentGetXmlEncodingMethod = Document.class
1164: .getMethod("getXmlEncoding", new Class[] {});
1165: fgDocumentMethodsAvailable = true;
1166: }
1167: // ClassNotFoundException, NoSuchMethodException or SecurityException
1168: // Whatever the case, we cannot retrieve the methods.
1169: catch (Exception exc) {
1170: fgDocumentGetXmlVersionMethod = null;
1171: fgDocumentGetInputEncodingMethod = null;
1172: fgDocumentGetXmlEncodingMethod = null;
1173: fgDocumentMethodsAvailable = false;
1174: }
1175: }
1176: }
1177:
1178: } //DOMSerializerImpl
|