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.xerces.parsers;
0019:
0020: import java.io.StringReader;
0021: import java.util.Locale;
0022: import java.util.Stack;
0023: import java.util.StringTokenizer;
0024: import java.util.Vector;
0025:
0026: import org.apache.xerces.dom.DOMErrorImpl;
0027: import org.apache.xerces.dom.DOMMessageFormatter;
0028: import org.apache.xerces.dom.DOMStringListImpl;
0029: import org.apache.xerces.impl.Constants;
0030: import org.apache.xerces.util.DOMEntityResolverWrapper;
0031: import org.apache.xerces.util.DOMErrorHandlerWrapper;
0032: import org.apache.xerces.util.DOMUtil;
0033: import org.apache.xerces.util.SymbolTable;
0034: import org.apache.xerces.util.XMLSymbols;
0035: import org.apache.xerces.xni.Augmentations;
0036: import org.apache.xerces.xni.NamespaceContext;
0037: import org.apache.xerces.xni.QName;
0038: import org.apache.xerces.xni.XMLAttributes;
0039: import org.apache.xerces.xni.XMLDTDContentModelHandler;
0040: import org.apache.xerces.xni.XMLDTDHandler;
0041: import org.apache.xerces.xni.XMLDocumentHandler;
0042: import org.apache.xerces.xni.XMLLocator;
0043: import org.apache.xerces.xni.XMLResourceIdentifier;
0044: import org.apache.xerces.xni.XMLString;
0045: import org.apache.xerces.xni.XNIException;
0046: import org.apache.xerces.xni.grammars.XMLGrammarPool;
0047: import org.apache.xerces.xni.parser.XMLConfigurationException;
0048: import org.apache.xerces.xni.parser.XMLDTDContentModelSource;
0049: import org.apache.xerces.xni.parser.XMLDTDSource;
0050: import org.apache.xerces.xni.parser.XMLDocumentSource;
0051: import org.apache.xerces.xni.parser.XMLEntityResolver;
0052: import org.apache.xerces.xni.parser.XMLInputSource;
0053: import org.apache.xerces.xni.parser.XMLParseException;
0054: import org.apache.xerces.xni.parser.XMLParserConfiguration;
0055: import org.w3c.dom.DOMConfiguration;
0056: import org.w3c.dom.DOMError;
0057: import org.w3c.dom.DOMErrorHandler;
0058: import org.w3c.dom.DOMException;
0059: import org.w3c.dom.DOMStringList;
0060: import org.w3c.dom.Document;
0061: import org.w3c.dom.Node;
0062: import org.w3c.dom.ls.LSException;
0063: import org.w3c.dom.ls.LSInput;
0064: import org.w3c.dom.ls.LSParser;
0065: import org.w3c.dom.ls.LSParserFilter;
0066: import org.w3c.dom.ls.LSResourceResolver;
0067: import org.xml.sax.SAXException;
0068:
0069: /**
0070: * This is Xerces DOM Builder class. It uses the abstract DOM
0071: * parser with a document scanner, a dtd scanner, and a validator, as
0072: * well as a grammar pool.
0073: *
0074: * @author Pavani Mukthipudi, Sun Microsystems Inc.
0075: * @author Elena Litani, IBM
0076: * @author Rahul Srivastava, Sun Microsystems Inc.
0077: * @version $Id: DOMParserImpl.java 568412 2007-08-22 04:40:44Z mrglavas $
0078: */
0079: public class DOMParserImpl extends AbstractDOMParser implements
0080: LSParser, DOMConfiguration {
0081:
0082: // SAX & Xerces feature ids
0083:
0084: /** Feature identifier: namespaces. */
0085: protected static final String NAMESPACES = Constants.SAX_FEATURE_PREFIX
0086: + Constants.NAMESPACES_FEATURE;
0087:
0088: /** Feature id: validation. */
0089: protected static final String VALIDATION_FEATURE = Constants.SAX_FEATURE_PREFIX
0090: + Constants.VALIDATION_FEATURE;
0091:
0092: /** XML Schema validation */
0093: protected static final String XMLSCHEMA = Constants.XERCES_FEATURE_PREFIX
0094: + Constants.SCHEMA_VALIDATION_FEATURE;
0095:
0096: /** XML Schema full checking */
0097: protected static final String XMLSCHEMA_FULL_CHECKING = Constants.XERCES_FEATURE_PREFIX
0098: + Constants.SCHEMA_FULL_CHECKING;
0099:
0100: /** Dynamic validation */
0101: protected static final String DYNAMIC_VALIDATION = Constants.XERCES_FEATURE_PREFIX
0102: + Constants.DYNAMIC_VALIDATION_FEATURE;
0103:
0104: /** Feature identifier: expose schema normalized value */
0105: protected static final String NORMALIZE_DATA = Constants.XERCES_FEATURE_PREFIX
0106: + Constants.SCHEMA_NORMALIZED_VALUE;
0107:
0108: /** Feature identifier: disallow docType Decls. */
0109: protected static final String DISALLOW_DOCTYPE_DECL_FEATURE = Constants.XERCES_FEATURE_PREFIX
0110: + Constants.DISALLOW_DOCTYPE_DECL_FEATURE;
0111:
0112: /** Feature identifier: honour all schemaLocations */
0113: protected static final String HONOUR_ALL_SCHEMALOCATIONS = Constants.XERCES_FEATURE_PREFIX
0114: + Constants.HONOUR_ALL_SCHEMALOCATIONS_FEATURE;
0115:
0116: // internal properties
0117: protected static final String SYMBOL_TABLE = Constants.XERCES_PROPERTY_PREFIX
0118: + Constants.SYMBOL_TABLE_PROPERTY;
0119:
0120: protected static final String PSVI_AUGMENT = Constants.XERCES_FEATURE_PREFIX
0121: + Constants.SCHEMA_AUGMENT_PSVI;
0122:
0123: //
0124: // Data
0125: //
0126:
0127: /** Include namespace declaration attributes in the document. **/
0128: protected boolean fNamespaceDeclarations = true;
0129:
0130: // REVISIT: this value should be null by default and should be set during creation of
0131: // LSParser
0132: protected String fSchemaType = null;
0133:
0134: protected boolean fBusy = false;
0135:
0136: private boolean abortNow = false;
0137:
0138: private Thread currentThread;
0139:
0140: protected final static boolean DEBUG = false;
0141:
0142: private Vector fSchemaLocations = new Vector();
0143: private String fSchemaLocation = null;
0144: private DOMStringList fRecognizedParameters;
0145:
0146: private AbortHandler abortHandler = new AbortHandler();
0147:
0148: //
0149: // Constructors
0150: //
0151:
0152: /**
0153: * Constructs a DOM Builder using the standard parser configuration.
0154: */
0155: public DOMParserImpl(String configuration, String schemaType) {
0156: this ((XMLParserConfiguration) ObjectFactory.createObject(
0157: "org.apache.xerces.xni.parser.XMLParserConfiguration",
0158: configuration));
0159: if (schemaType != null) {
0160: if (schemaType.equals(Constants.NS_DTD)) {
0161: //Schema validation is false by default and hence there is no
0162: //need to set it to false here. Also, schema validation is
0163: //not a recognized feature for DTDConfiguration's and so
0164: //setting this feature here would result in a Configuration
0165: //Exception.
0166: fConfiguration.setProperty(
0167: Constants.JAXP_PROPERTY_PREFIX
0168: + Constants.SCHEMA_LANGUAGE,
0169: Constants.NS_DTD);
0170: fSchemaType = Constants.NS_DTD;
0171: } else if (schemaType.equals(Constants.NS_XMLSCHEMA)) {
0172: // XML Schem validation
0173: fConfiguration.setProperty(
0174: Constants.JAXP_PROPERTY_PREFIX
0175: + Constants.SCHEMA_LANGUAGE,
0176: Constants.NS_XMLSCHEMA);
0177: }
0178: }
0179:
0180: }
0181:
0182: /**
0183: * Constructs a DOM Builder using the specified parser configuration.
0184: */
0185: public DOMParserImpl(XMLParserConfiguration config) {
0186: super (config);
0187:
0188: // add recognized features
0189: final String[] domRecognizedFeatures = {
0190: Constants.DOM_CANONICAL_FORM,
0191: Constants.DOM_CDATA_SECTIONS,
0192: Constants.DOM_CHARSET_OVERRIDES_XML_ENCODING,
0193: Constants.DOM_INFOSET,
0194: Constants.DOM_NAMESPACE_DECLARATIONS,
0195: Constants.DOM_SPLIT_CDATA,
0196: Constants.DOM_SUPPORTED_MEDIATYPES_ONLY,
0197: Constants.DOM_CERTIFIED,
0198: Constants.DOM_WELLFORMED,
0199: Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS, };
0200:
0201: fConfiguration.addRecognizedFeatures(domRecognizedFeatures);
0202:
0203: // turn off deferred DOM
0204: fConfiguration.setFeature(DEFER_NODE_EXPANSION, false);
0205:
0206: // Set values so that the value of the
0207: // infoset parameter is true (its default value).
0208: //
0209: // true: namespace-declarations, well-formed,
0210: // element-content-whitespace, comments, namespaces
0211: //
0212: // false: validate-if-schema, entities,
0213: // datatype-normalization, cdata-sections
0214:
0215: fConfiguration.setFeature(Constants.DOM_NAMESPACE_DECLARATIONS,
0216: true);
0217: fConfiguration.setFeature(Constants.DOM_WELLFORMED, true);
0218: fConfiguration.setFeature(INCLUDE_COMMENTS_FEATURE, true);
0219: fConfiguration.setFeature(INCLUDE_IGNORABLE_WHITESPACE, true);
0220: fConfiguration.setFeature(NAMESPACES, true);
0221:
0222: fConfiguration.setFeature(DYNAMIC_VALIDATION, false);
0223: fConfiguration.setFeature(CREATE_ENTITY_REF_NODES, false);
0224: fConfiguration.setFeature(CREATE_CDATA_NODES_FEATURE, false);
0225:
0226: // set other default values
0227: fConfiguration.setFeature(Constants.DOM_CANONICAL_FORM, false);
0228: fConfiguration.setFeature(
0229: Constants.DOM_CHARSET_OVERRIDES_XML_ENCODING, true);
0230: fConfiguration.setFeature(Constants.DOM_SPLIT_CDATA, true);
0231: fConfiguration.setFeature(
0232: Constants.DOM_SUPPORTED_MEDIATYPES_ONLY, false);
0233: fConfiguration
0234: .setFeature(
0235: Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS,
0236: true);
0237:
0238: // REVISIT: by default Xerces assumes that input is certified.
0239: // default is different from the one specified in the DOM spec
0240: fConfiguration.setFeature(Constants.DOM_CERTIFIED, true);
0241:
0242: // Xerces datatype-normalization feature is on by default
0243: // This is a recognized feature only for XML Schemas. If the
0244: // configuration doesn't support this feature, ignore it.
0245: try {
0246: fConfiguration.setFeature(NORMALIZE_DATA, false);
0247: } catch (XMLConfigurationException exc) {
0248: }
0249:
0250: } // <init>(XMLParserConfiguration)
0251:
0252: /**
0253: * Constructs a DOM Builder using the specified symbol table.
0254: */
0255: public DOMParserImpl(SymbolTable symbolTable) {
0256: this (
0257: (XMLParserConfiguration) ObjectFactory
0258: .createObject(
0259: "org.apache.xerces.xni.parser.XMLParserConfiguration",
0260: "org.apache.xerces.parsers.XIncludeAwareParserConfiguration"));
0261: fConfiguration.setProperty(Constants.XERCES_PROPERTY_PREFIX
0262: + Constants.SYMBOL_TABLE_PROPERTY, symbolTable);
0263: } // <init>(SymbolTable)
0264:
0265: /**
0266: * Constructs a DOM Builder using the specified symbol table and
0267: * grammar pool.
0268: */
0269: public DOMParserImpl(SymbolTable symbolTable,
0270: XMLGrammarPool grammarPool) {
0271: this (
0272: (XMLParserConfiguration) ObjectFactory
0273: .createObject(
0274: "org.apache.xerces.xni.parser.XMLParserConfiguration",
0275: "org.apache.xerces.parsers.XIncludeAwareParserConfiguration"));
0276: fConfiguration.setProperty(Constants.XERCES_PROPERTY_PREFIX
0277: + Constants.SYMBOL_TABLE_PROPERTY, symbolTable);
0278: fConfiguration.setProperty(Constants.XERCES_PROPERTY_PREFIX
0279: + Constants.XMLGRAMMAR_POOL_PROPERTY, grammarPool);
0280: }
0281:
0282: /**
0283: * Resets the parser state.
0284: *
0285: * @throws SAXException Thrown on initialization error.
0286: */
0287: public void reset() {
0288: super .reset();
0289:
0290: // get state of namespace-declarations parameter.
0291: fNamespaceDeclarations = fConfiguration
0292: .getFeature(Constants.DOM_NAMESPACE_DECLARATIONS);
0293:
0294: // DOM Filter
0295: if (fSkippedElemStack != null) {
0296: fSkippedElemStack.removeAllElements();
0297: }
0298: fSchemaLocations.clear();
0299: fRejectedElement.clear();
0300: fFilterReject = false;
0301: fSchemaType = null;
0302:
0303: } // reset()
0304:
0305: //
0306: // DOMParser methods
0307: //
0308:
0309: public DOMConfiguration getDomConfig() {
0310: return this ;
0311: }
0312:
0313: /**
0314: * When the application provides a filter, the parser will call out to
0315: * the filter at the completion of the construction of each
0316: * <code>Element</code> node. The filter implementation can choose to
0317: * remove the element from the document being constructed (unless the
0318: * element is the document element) or to terminate the parse early. If
0319: * the document is being validated when it's loaded the validation
0320: * happens before the filter is called.
0321: */
0322: public LSParserFilter getFilter() {
0323: return fDOMFilter;
0324: }
0325:
0326: /**
0327: * When the application provides a filter, the parser will call out to
0328: * the filter at the completion of the construction of each
0329: * <code>Element</code> node. The filter implementation can choose to
0330: * remove the element from the document being constructed (unless the
0331: * element is the document element) or to terminate the parse early. If
0332: * the document is being validated when it's loaded the validation
0333: * happens before the filter is called.
0334: */
0335: public void setFilter(LSParserFilter filter) {
0336: fDOMFilter = filter;
0337: if (fSkippedElemStack == null) {
0338: fSkippedElemStack = new Stack();
0339: }
0340: }
0341:
0342: /**
0343: * Set parameters and properties
0344: */
0345: public void setParameter(String name, Object value)
0346: throws DOMException {
0347: // set features
0348:
0349: if (value instanceof Boolean) {
0350: boolean state = ((Boolean) value).booleanValue();
0351: try {
0352: if (name.equalsIgnoreCase(Constants.DOM_COMMENTS)) {
0353: fConfiguration.setFeature(INCLUDE_COMMENTS_FEATURE,
0354: state);
0355: } else if (name
0356: .equalsIgnoreCase(Constants.DOM_DATATYPE_NORMALIZATION)) {
0357: fConfiguration.setFeature(NORMALIZE_DATA, state);
0358: } else if (name
0359: .equalsIgnoreCase(Constants.DOM_ENTITIES)) {
0360: fConfiguration.setFeature(CREATE_ENTITY_REF_NODES,
0361: state);
0362: } else if (name
0363: .equalsIgnoreCase(Constants.DOM_DISALLOW_DOCTYPE)) {
0364: fConfiguration.setFeature(
0365: DISALLOW_DOCTYPE_DECL_FEATURE, state);
0366: } else if (name
0367: .equalsIgnoreCase(Constants.DOM_SUPPORTED_MEDIATYPES_ONLY)
0368: || name
0369: .equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)
0370: || name
0371: .equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION)
0372: || name
0373: .equalsIgnoreCase(Constants.DOM_CANONICAL_FORM)) {
0374: if (state) { // true is not supported
0375: String msg = DOMMessageFormatter.formatMessage(
0376: DOMMessageFormatter.DOM_DOMAIN,
0377: "FEATURE_NOT_SUPPORTED",
0378: new Object[] { name });
0379: throw new DOMException(
0380: DOMException.NOT_SUPPORTED_ERR, msg);
0381: }
0382: // setting those features to false is no-op
0383: } else if (name
0384: .equalsIgnoreCase(Constants.DOM_NAMESPACES)) {
0385: fConfiguration.setFeature(NAMESPACES, state);
0386: } else if (name.equalsIgnoreCase(Constants.DOM_INFOSET)) {
0387: // Setting false has no effect.
0388: if (state) {
0389: // true: namespaces, namespace-declarations,
0390: // comments, element-content-whitespace
0391: fConfiguration.setFeature(NAMESPACES, true);
0392: fConfiguration.setFeature(
0393: Constants.DOM_NAMESPACE_DECLARATIONS,
0394: true);
0395: fConfiguration.setFeature(
0396: INCLUDE_COMMENTS_FEATURE, true);
0397: fConfiguration.setFeature(
0398: INCLUDE_IGNORABLE_WHITESPACE, true);
0399:
0400: // false: validate-if-schema, entities,
0401: // datatype-normalization, cdata-sections
0402: fConfiguration.setFeature(DYNAMIC_VALIDATION,
0403: false);
0404: fConfiguration.setFeature(
0405: CREATE_ENTITY_REF_NODES, false);
0406: fConfiguration
0407: .setFeature(NORMALIZE_DATA, false);
0408: fConfiguration.setFeature(
0409: CREATE_CDATA_NODES_FEATURE, false);
0410: }
0411: } else if (name
0412: .equalsIgnoreCase(Constants.DOM_CDATA_SECTIONS)) {
0413: fConfiguration.setFeature(
0414: CREATE_CDATA_NODES_FEATURE, state);
0415: } else if (name
0416: .equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS)) {
0417: fConfiguration
0418: .setFeature(
0419: Constants.DOM_NAMESPACE_DECLARATIONS,
0420: state);
0421: } else if (name
0422: .equalsIgnoreCase(Constants.DOM_WELLFORMED)
0423: || name
0424: .equalsIgnoreCase(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) {
0425: if (!state) { // false is not supported
0426: String msg = DOMMessageFormatter.formatMessage(
0427: DOMMessageFormatter.DOM_DOMAIN,
0428: "FEATURE_NOT_SUPPORTED",
0429: new Object[] { name });
0430: throw new DOMException(
0431: DOMException.NOT_SUPPORTED_ERR, msg);
0432: }
0433: // setting these features to true is no-op
0434: // REVISIT: implement "namespace-declaration" feature
0435: } else if (name
0436: .equalsIgnoreCase(Constants.DOM_VALIDATE)) {
0437: fConfiguration
0438: .setFeature(VALIDATION_FEATURE, state);
0439: if (fSchemaType != Constants.NS_DTD) {
0440: fConfiguration.setFeature(XMLSCHEMA, state);
0441: fConfiguration.setFeature(
0442: XMLSCHEMA_FULL_CHECKING, state);
0443: }
0444: if (state) {
0445: fConfiguration.setFeature(DYNAMIC_VALIDATION,
0446: false);
0447: }
0448: } else if (name
0449: .equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA)) {
0450: fConfiguration
0451: .setFeature(DYNAMIC_VALIDATION, state);
0452: // Note: validation and dynamic validation are mutually exclusive
0453: if (state) {
0454: fConfiguration.setFeature(VALIDATION_FEATURE,
0455: false);
0456: }
0457: } else if (name
0458: .equalsIgnoreCase(Constants.DOM_ELEMENT_CONTENT_WHITESPACE)) {
0459: fConfiguration.setFeature(
0460: INCLUDE_IGNORABLE_WHITESPACE, state);
0461: } else if (name.equalsIgnoreCase(Constants.DOM_PSVI)) {
0462: //XSModel - turn on PSVI augmentation
0463: fConfiguration.setFeature(PSVI_AUGMENT, true);
0464: fConfiguration.setProperty(DOCUMENT_CLASS_NAME,
0465: "org.apache.xerces.dom.PSVIDocumentImpl");
0466: } else {
0467: // Constants.DOM_CHARSET_OVERRIDES_XML_ENCODING feature,
0468: // Constants.DOM_SPLIT_CDATA feature,
0469: // or any Xerces feature
0470: String normalizedName;
0471: // The honour-all-schemaLocations feature is
0472: // mixed case so requires special treatment.
0473: if (name
0474: .equalsIgnoreCase(HONOUR_ALL_SCHEMALOCATIONS)) {
0475: normalizedName = HONOUR_ALL_SCHEMALOCATIONS;
0476: } else {
0477: normalizedName = name
0478: .toLowerCase(Locale.ENGLISH);
0479: }
0480: fConfiguration.setFeature(normalizedName, state);
0481: }
0482:
0483: } catch (XMLConfigurationException e) {
0484: String msg = DOMMessageFormatter.formatMessage(
0485: DOMMessageFormatter.DOM_DOMAIN,
0486: "FEATURE_NOT_FOUND", new Object[] { name });
0487: throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
0488: }
0489: } else { // set properties
0490: if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER)) {
0491: if (value instanceof DOMErrorHandler || value == null) {
0492: try {
0493: fErrorHandler = new DOMErrorHandlerWrapper(
0494: (DOMErrorHandler) value);
0495: fConfiguration.setProperty(ERROR_HANDLER,
0496: fErrorHandler);
0497: } catch (XMLConfigurationException e) {
0498: }
0499: } else {
0500: // REVISIT: type mismatch
0501: String msg = DOMMessageFormatter.formatMessage(
0502: DOMMessageFormatter.DOM_DOMAIN,
0503: "TYPE_MISMATCH_ERR", new Object[] { name });
0504: throw new DOMException(
0505: DOMException.TYPE_MISMATCH_ERR, msg);
0506: }
0507:
0508: } else if (name
0509: .equalsIgnoreCase(Constants.DOM_RESOURCE_RESOLVER)) {
0510: if (value instanceof LSResourceResolver
0511: || value == null) {
0512: try {
0513: fConfiguration.setProperty(ENTITY_RESOLVER,
0514: new DOMEntityResolverWrapper(
0515: (LSResourceResolver) value));
0516: } catch (XMLConfigurationException e) {
0517: }
0518: } else {
0519: // REVISIT: type mismatch
0520: String msg = DOMMessageFormatter.formatMessage(
0521: DOMMessageFormatter.DOM_DOMAIN,
0522: "TYPE_MISMATCH_ERR", new Object[] { name });
0523: throw new DOMException(
0524: DOMException.TYPE_MISMATCH_ERR, msg);
0525: }
0526:
0527: } else if (name
0528: .equalsIgnoreCase(Constants.DOM_SCHEMA_LOCATION)) {
0529: if (value instanceof String || value == null) {
0530: try {
0531: if (value == null) {
0532: fSchemaLocation = null;
0533: fConfiguration.setProperty(
0534: Constants.JAXP_PROPERTY_PREFIX
0535: + Constants.SCHEMA_SOURCE,
0536: null);
0537: } else {
0538: fSchemaLocation = (String) value;
0539: // map DOM schema-location to JAXP schemaSource property
0540: // tokenize location string
0541: StringTokenizer t = new StringTokenizer(
0542: fSchemaLocation, " \n\t\r");
0543: if (t.hasMoreTokens()) {
0544: fSchemaLocations.clear();
0545: fSchemaLocations.add(t.nextToken());
0546: while (t.hasMoreTokens()) {
0547: fSchemaLocations.add(t.nextToken());
0548: }
0549: fConfiguration
0550: .setProperty(
0551: Constants.JAXP_PROPERTY_PREFIX
0552: + Constants.SCHEMA_SOURCE,
0553: fSchemaLocations
0554: .toArray());
0555: } else {
0556: fConfiguration
0557: .setProperty(
0558: Constants.JAXP_PROPERTY_PREFIX
0559: + Constants.SCHEMA_SOURCE,
0560: value);
0561: }
0562: }
0563: } catch (XMLConfigurationException e) {
0564: }
0565: } else {
0566: // REVISIT: type mismatch
0567: String msg = DOMMessageFormatter.formatMessage(
0568: DOMMessageFormatter.DOM_DOMAIN,
0569: "TYPE_MISMATCH_ERR", new Object[] { name });
0570: throw new DOMException(
0571: DOMException.TYPE_MISMATCH_ERR, msg);
0572: }
0573:
0574: } else if (name.equalsIgnoreCase(Constants.DOM_SCHEMA_TYPE)) {
0575: if (value instanceof String || value == null) {
0576: try {
0577: if (value == null) {
0578: // turn off schema features
0579: fConfiguration.setFeature(XMLSCHEMA, false);
0580: fConfiguration.setFeature(
0581: XMLSCHEMA_FULL_CHECKING, false);
0582: // map to JAXP schemaLanguage
0583: fConfiguration
0584: .setProperty(
0585: Constants.JAXP_PROPERTY_PREFIX
0586: + Constants.SCHEMA_LANGUAGE,
0587: null);
0588: fSchemaType = null;
0589: } else if (value.equals(Constants.NS_XMLSCHEMA)) {
0590: // turn on schema features
0591: fConfiguration.setFeature(XMLSCHEMA, true);
0592: fConfiguration.setFeature(
0593: XMLSCHEMA_FULL_CHECKING, true);
0594: // map to JAXP schemaLanguage
0595: fConfiguration
0596: .setProperty(
0597: Constants.JAXP_PROPERTY_PREFIX
0598: + Constants.SCHEMA_LANGUAGE,
0599: Constants.NS_XMLSCHEMA);
0600: fSchemaType = Constants.NS_XMLSCHEMA;
0601: } else if (value.equals(Constants.NS_DTD)) {
0602: // turn off schema features
0603: fConfiguration.setFeature(XMLSCHEMA, false);
0604: fConfiguration.setFeature(
0605: XMLSCHEMA_FULL_CHECKING, false);
0606: // map to JAXP schemaLanguage
0607: fConfiguration
0608: .setProperty(
0609: Constants.JAXP_PROPERTY_PREFIX
0610: + Constants.SCHEMA_LANGUAGE,
0611: Constants.NS_DTD);
0612: fSchemaType = Constants.NS_DTD;
0613: }
0614: } catch (XMLConfigurationException e) {
0615: }
0616: } else {
0617: String msg = DOMMessageFormatter.formatMessage(
0618: DOMMessageFormatter.DOM_DOMAIN,
0619: "TYPE_MISMATCH_ERR", new Object[] { name });
0620: throw new DOMException(
0621: DOMException.TYPE_MISMATCH_ERR, msg);
0622: }
0623:
0624: } else if (name.equalsIgnoreCase(DOCUMENT_CLASS_NAME)) {
0625: fConfiguration.setProperty(DOCUMENT_CLASS_NAME, value);
0626: } else {
0627: // Try to set the property.
0628: String normalizedName = name
0629: .toLowerCase(Locale.ENGLISH);
0630: try {
0631: fConfiguration.setProperty(normalizedName, value);
0632: return;
0633: } catch (XMLConfigurationException e) {
0634: }
0635:
0636: // If this is a boolean parameter a type mismatch should be thrown.
0637: try {
0638: // The honour-all-schemaLocations feature is
0639: // mixed case so requires special treatment.
0640: if (name
0641: .equalsIgnoreCase(HONOUR_ALL_SCHEMALOCATIONS)) {
0642: normalizedName = HONOUR_ALL_SCHEMALOCATIONS;
0643: }
0644: fConfiguration.getFeature(normalizedName);
0645: String msg = DOMMessageFormatter.formatMessage(
0646: DOMMessageFormatter.DOM_DOMAIN,
0647: "TYPE_MISMATCH_ERR", new Object[] { name });
0648: throw new DOMException(
0649: DOMException.TYPE_MISMATCH_ERR, msg);
0650:
0651: } catch (XMLConfigurationException e) {
0652: }
0653:
0654: // Parameter is not recognized
0655: String msg = DOMMessageFormatter.formatMessage(
0656: DOMMessageFormatter.DOM_DOMAIN,
0657: "FEATURE_NOT_FOUND", new Object[] { name });
0658: throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
0659: }
0660: }
0661: }
0662:
0663: /**
0664: * Look up the value of a feature or a property.
0665: */
0666: public Object getParameter(String name) throws DOMException {
0667: if (name.equalsIgnoreCase(Constants.DOM_COMMENTS)) {
0668: return (fConfiguration.getFeature(INCLUDE_COMMENTS_FEATURE)) ? Boolean.TRUE
0669: : Boolean.FALSE;
0670: } else if (name
0671: .equalsIgnoreCase(Constants.DOM_DATATYPE_NORMALIZATION)) {
0672: return (fConfiguration.getFeature(NORMALIZE_DATA)) ? Boolean.TRUE
0673: : Boolean.FALSE;
0674: } else if (name.equalsIgnoreCase(Constants.DOM_ENTITIES)) {
0675: return (fConfiguration.getFeature(CREATE_ENTITY_REF_NODES)) ? Boolean.TRUE
0676: : Boolean.FALSE;
0677: } else if (name.equalsIgnoreCase(Constants.DOM_NAMESPACES)) {
0678: return (fConfiguration.getFeature(NAMESPACES)) ? Boolean.TRUE
0679: : Boolean.FALSE;
0680: } else if (name.equalsIgnoreCase(Constants.DOM_VALIDATE)) {
0681: return (fConfiguration.getFeature(VALIDATION_FEATURE)) ? Boolean.TRUE
0682: : Boolean.FALSE;
0683: } else if (name
0684: .equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA)) {
0685: return (fConfiguration.getFeature(DYNAMIC_VALIDATION)) ? Boolean.TRUE
0686: : Boolean.FALSE;
0687: } else if (name
0688: .equalsIgnoreCase(Constants.DOM_ELEMENT_CONTENT_WHITESPACE)) {
0689: return (fConfiguration
0690: .getFeature(INCLUDE_IGNORABLE_WHITESPACE)) ? Boolean.TRUE
0691: : Boolean.FALSE;
0692: } else if (name
0693: .equalsIgnoreCase(Constants.DOM_DISALLOW_DOCTYPE)) {
0694: return (fConfiguration
0695: .getFeature(DISALLOW_DOCTYPE_DECL_FEATURE)) ? Boolean.TRUE
0696: : Boolean.FALSE;
0697: } else if (name.equalsIgnoreCase(Constants.DOM_INFOSET)) {
0698: // REVISIT: This is somewhat expensive to compute
0699: // but it's possible that the user has a reference
0700: // to the configuration and is changing the values
0701: // of these features directly on it.
0702: boolean infoset = fConfiguration.getFeature(NAMESPACES)
0703: && fConfiguration
0704: .getFeature(Constants.DOM_NAMESPACE_DECLARATIONS)
0705: && fConfiguration
0706: .getFeature(INCLUDE_COMMENTS_FEATURE)
0707: && fConfiguration
0708: .getFeature(INCLUDE_IGNORABLE_WHITESPACE)
0709: && !fConfiguration.getFeature(DYNAMIC_VALIDATION)
0710: && !fConfiguration
0711: .getFeature(CREATE_ENTITY_REF_NODES)
0712: && !fConfiguration.getFeature(NORMALIZE_DATA)
0713: && !fConfiguration
0714: .getFeature(CREATE_CDATA_NODES_FEATURE);
0715: return (infoset) ? Boolean.TRUE : Boolean.FALSE;
0716: } else if (name.equalsIgnoreCase(Constants.DOM_CDATA_SECTIONS)) {
0717: return (fConfiguration
0718: .getFeature(CREATE_CDATA_NODES_FEATURE)) ? Boolean.TRUE
0719: : Boolean.FALSE;
0720: } else if (name
0721: .equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION)
0722: || name
0723: .equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)) {
0724: return Boolean.FALSE;
0725: } else if (name
0726: .equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS)
0727: || name.equalsIgnoreCase(Constants.DOM_WELLFORMED)
0728: || name
0729: .equalsIgnoreCase(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)
0730: || name.equalsIgnoreCase(Constants.DOM_CANONICAL_FORM)
0731: || name
0732: .equalsIgnoreCase(Constants.DOM_SUPPORTED_MEDIATYPES_ONLY)
0733: || name.equalsIgnoreCase(Constants.DOM_SPLIT_CDATA)
0734: || name
0735: .equalsIgnoreCase(Constants.DOM_CHARSET_OVERRIDES_XML_ENCODING)) {
0736: return (fConfiguration.getFeature(name
0737: .toLowerCase(Locale.ENGLISH))) ? Boolean.TRUE
0738: : Boolean.FALSE;
0739: } else if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER)) {
0740: if (fErrorHandler != null) {
0741: return fErrorHandler.getErrorHandler();
0742: }
0743: return null;
0744: } else if (name
0745: .equalsIgnoreCase(Constants.DOM_RESOURCE_RESOLVER)) {
0746: try {
0747: XMLEntityResolver entityResolver = (XMLEntityResolver) fConfiguration
0748: .getProperty(ENTITY_RESOLVER);
0749: if (entityResolver != null
0750: && entityResolver instanceof DOMEntityResolverWrapper) {
0751: return ((DOMEntityResolverWrapper) entityResolver)
0752: .getEntityResolver();
0753: }
0754: } catch (XMLConfigurationException e) {
0755: }
0756: return null;
0757: } else if (name.equalsIgnoreCase(Constants.DOM_SCHEMA_TYPE)) {
0758: return fConfiguration
0759: .getProperty(Constants.JAXP_PROPERTY_PREFIX
0760: + Constants.SCHEMA_LANGUAGE);
0761: } else if (name.equalsIgnoreCase(Constants.DOM_SCHEMA_LOCATION)) {
0762: return fSchemaLocation;
0763: } else if (name.equalsIgnoreCase(SYMBOL_TABLE)) {
0764: return fConfiguration.getProperty(SYMBOL_TABLE);
0765: } else if (name.equalsIgnoreCase(DOCUMENT_CLASS_NAME)) {
0766: return fConfiguration.getProperty(DOCUMENT_CLASS_NAME);
0767: } else {
0768: // This could be a recognized feature or property.
0769: String normalizedName;
0770:
0771: // The honour-all-schemaLocations feature is
0772: // mixed case so requires special treatment.
0773: if (name.equalsIgnoreCase(HONOUR_ALL_SCHEMALOCATIONS)) {
0774: normalizedName = HONOUR_ALL_SCHEMALOCATIONS;
0775: } else {
0776: normalizedName = name.toLowerCase(Locale.ENGLISH);
0777: }
0778: try {
0779: return fConfiguration.getFeature(normalizedName) ? Boolean.TRUE
0780: : Boolean.FALSE;
0781: } catch (XMLConfigurationException e) {
0782: }
0783:
0784: // This isn't a feature; perhaps it's a property
0785: try {
0786: return fConfiguration.getProperty(normalizedName);
0787: } catch (XMLConfigurationException e) {
0788: }
0789:
0790: String msg = DOMMessageFormatter.formatMessage(
0791: DOMMessageFormatter.DOM_DOMAIN,
0792: "FEATURE_NOT_FOUND", new Object[] { name });
0793: throw new DOMException(DOMException.NOT_FOUND_ERR, msg);
0794: }
0795: }
0796:
0797: public boolean canSetParameter(String name, Object value) {
0798: if (value == null) {
0799: return true;
0800: }
0801:
0802: if (value instanceof Boolean) {
0803: boolean state = ((Boolean) value).booleanValue();
0804: if (name
0805: .equalsIgnoreCase(Constants.DOM_SUPPORTED_MEDIATYPES_ONLY)
0806: || name
0807: .equalsIgnoreCase(Constants.DOM_NORMALIZE_CHARACTERS)
0808: || name
0809: .equalsIgnoreCase(Constants.DOM_CHECK_CHAR_NORMALIZATION)
0810: || name
0811: .equalsIgnoreCase(Constants.DOM_CANONICAL_FORM)) {
0812: // true is not supported
0813: return (state) ? false : true;
0814: } else if (name.equalsIgnoreCase(Constants.DOM_WELLFORMED)
0815: || name
0816: .equalsIgnoreCase(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) {
0817: // false is not supported
0818: return (state) ? true : false;
0819: } else if (name
0820: .equalsIgnoreCase(Constants.DOM_CDATA_SECTIONS)
0821: || name
0822: .equalsIgnoreCase(Constants.DOM_CHARSET_OVERRIDES_XML_ENCODING)
0823: || name.equalsIgnoreCase(Constants.DOM_COMMENTS)
0824: || name
0825: .equalsIgnoreCase(Constants.DOM_DATATYPE_NORMALIZATION)
0826: || name
0827: .equalsIgnoreCase(Constants.DOM_DISALLOW_DOCTYPE)
0828: || name.equalsIgnoreCase(Constants.DOM_ENTITIES)
0829: || name.equalsIgnoreCase(Constants.DOM_INFOSET)
0830: || name.equalsIgnoreCase(Constants.DOM_NAMESPACES)
0831: || name
0832: .equalsIgnoreCase(Constants.DOM_NAMESPACE_DECLARATIONS)
0833: || name.equalsIgnoreCase(Constants.DOM_VALIDATE)
0834: || name
0835: .equalsIgnoreCase(Constants.DOM_VALIDATE_IF_SCHEMA)
0836: || name
0837: .equalsIgnoreCase(Constants.DOM_ELEMENT_CONTENT_WHITESPACE)
0838: || name.equalsIgnoreCase(Constants.DOM_XMLDECL)) {
0839: return true;
0840: }
0841:
0842: // Recognize Xerces features.
0843: try {
0844: String normalizedName;
0845: // The honour-all-schemaLocations feature is
0846: // mixed case so requires special treatment.
0847: if (name.equalsIgnoreCase(HONOUR_ALL_SCHEMALOCATIONS)) {
0848: normalizedName = HONOUR_ALL_SCHEMALOCATIONS;
0849: } else {
0850: normalizedName = name.toLowerCase(Locale.ENGLISH);
0851: }
0852: fConfiguration.getFeature(normalizedName);
0853: return true;
0854: } catch (XMLConfigurationException e) {
0855: return false;
0856: }
0857: } else { // check properties
0858: if (name.equalsIgnoreCase(Constants.DOM_ERROR_HANDLER)) {
0859: if (value instanceof DOMErrorHandler || value == null) {
0860: return true;
0861: }
0862: return false;
0863: } else if (name
0864: .equalsIgnoreCase(Constants.DOM_RESOURCE_RESOLVER)) {
0865: if (value instanceof LSResourceResolver
0866: || value == null) {
0867: return true;
0868: }
0869: return false;
0870: } else if (name.equalsIgnoreCase(Constants.DOM_SCHEMA_TYPE)) {
0871: if ((value instanceof String && (value
0872: .equals(Constants.NS_XMLSCHEMA) || value
0873: .equals(Constants.NS_DTD)))
0874: || value == null) {
0875: return true;
0876: }
0877: return false;
0878: } else if (name
0879: .equalsIgnoreCase(Constants.DOM_SCHEMA_LOCATION)) {
0880: if (value instanceof String || value == null)
0881: return true;
0882: return false;
0883: } else if (name.equalsIgnoreCase(DOCUMENT_CLASS_NAME)) {
0884: return true;
0885: }
0886:
0887: // Recognize Xerces properties.
0888: try {
0889: fConfiguration.getProperty(name
0890: .toLowerCase(Locale.ENGLISH));
0891: return true;
0892: } catch (XMLConfigurationException e) {
0893: return false;
0894: }
0895: }
0896: }
0897:
0898: /**
0899: * DOM Level 3 CR - Experimental.
0900: *
0901: * The list of the parameters supported by this
0902: * <code>DOMConfiguration</code> object and for which at least one value
0903: * can be set by the application. Note that this list can also contain
0904: * parameter names defined outside this specification.
0905: */
0906: public DOMStringList getParameterNames() {
0907: if (fRecognizedParameters == null) {
0908: Vector parameters = new Vector();
0909:
0910: // REVISIT: add Xerces recognized properties/features
0911: parameters.add(Constants.DOM_NAMESPACES);
0912: parameters.add(Constants.DOM_CDATA_SECTIONS);
0913: parameters.add(Constants.DOM_CANONICAL_FORM);
0914: parameters.add(Constants.DOM_NAMESPACE_DECLARATIONS);
0915: parameters.add(Constants.DOM_SPLIT_CDATA);
0916:
0917: parameters.add(Constants.DOM_ENTITIES);
0918: parameters.add(Constants.DOM_VALIDATE_IF_SCHEMA);
0919: parameters.add(Constants.DOM_VALIDATE);
0920: parameters.add(Constants.DOM_DATATYPE_NORMALIZATION);
0921:
0922: parameters
0923: .add(Constants.DOM_CHARSET_OVERRIDES_XML_ENCODING);
0924: parameters.add(Constants.DOM_CHECK_CHAR_NORMALIZATION);
0925: parameters.add(Constants.DOM_SUPPORTED_MEDIATYPES_ONLY);
0926: parameters
0927: .add(Constants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS);
0928:
0929: parameters.add(Constants.DOM_NORMALIZE_CHARACTERS);
0930: parameters.add(Constants.DOM_WELLFORMED);
0931: parameters.add(Constants.DOM_INFOSET);
0932: parameters.add(Constants.DOM_DISALLOW_DOCTYPE);
0933: parameters.add(Constants.DOM_ELEMENT_CONTENT_WHITESPACE);
0934: parameters.add(Constants.DOM_COMMENTS);
0935:
0936: parameters.add(Constants.DOM_ERROR_HANDLER);
0937: parameters.add(Constants.DOM_RESOURCE_RESOLVER);
0938: parameters.add(Constants.DOM_SCHEMA_LOCATION);
0939: parameters.add(Constants.DOM_SCHEMA_TYPE);
0940:
0941: fRecognizedParameters = new DOMStringListImpl(parameters);
0942:
0943: }
0944:
0945: return fRecognizedParameters;
0946: }
0947:
0948: /**
0949: * Parse an XML document from a location identified by an URI reference.
0950: * If the URI contains a fragment identifier (see section 4.1 in ), the
0951: * behavior is not defined by this specification.
0952: *
0953: */
0954: public Document parseURI(String uri) throws LSException {
0955:
0956: //If DOMParser insstance is already busy parsing another document when this
0957: // method is called, then raise INVALID_STATE_ERR according to DOM L3 LS spec
0958: if (fBusy) {
0959: String msg = DOMMessageFormatter.formatMessage(
0960: DOMMessageFormatter.DOM_DOMAIN,
0961: "INVALID_STATE_ERR", null);
0962: throw new DOMException(DOMException.INVALID_STATE_ERR, msg);
0963: }
0964:
0965: XMLInputSource source = new XMLInputSource(null, uri, null);
0966: try {
0967: currentThread = Thread.currentThread();
0968: fBusy = true;
0969: parse(source);
0970: fBusy = false;
0971: if (abortNow && currentThread.isInterrupted()) {
0972: //reset interrupt state
0973: abortNow = false;
0974: Thread.interrupted();
0975: }
0976: } catch (Exception e) {
0977: fBusy = false;
0978: if (abortNow && currentThread.isInterrupted()) {
0979: Thread.interrupted();
0980: }
0981: if (abortNow) {
0982: abortNow = false;
0983: restoreHandlers();
0984: return null;
0985: }
0986: // Consume this exception if the user
0987: // issued an interrupt or an abort.
0988: if (e != ABORT) {
0989: if (!(e instanceof XMLParseException)
0990: && fErrorHandler != null) {
0991: DOMErrorImpl error = new DOMErrorImpl();
0992: error.fException = e;
0993: error.fMessage = e.getMessage();
0994: error.fSeverity = DOMError.SEVERITY_FATAL_ERROR;
0995: fErrorHandler.getErrorHandler().handleError(error);
0996: }
0997: if (DEBUG) {
0998: e.printStackTrace();
0999: }
1000: throw (LSException) DOMUtil.createLSException(
1001: LSException.PARSE_ERR, e).fillInStackTrace();
1002: }
1003: }
1004: Document doc = getDocument();
1005: dropDocumentReferences();
1006: return doc;
1007: }
1008:
1009: /**
1010: * Parse an XML document from a resource identified by an
1011: * <code>LSInput</code>.
1012: *
1013: */
1014: public Document parse(LSInput is) throws LSException {
1015:
1016: // need to wrap the LSInput with an XMLInputSource
1017: XMLInputSource xmlInputSource = dom2xmlInputSource(is);
1018: if (fBusy) {
1019: String msg = DOMMessageFormatter.formatMessage(
1020: DOMMessageFormatter.DOM_DOMAIN,
1021: "INVALID_STATE_ERR", null);
1022: throw new DOMException(DOMException.INVALID_STATE_ERR, msg);
1023: }
1024:
1025: try {
1026: currentThread = Thread.currentThread();
1027: fBusy = true;
1028: parse(xmlInputSource);
1029: fBusy = false;
1030: if (abortNow && currentThread.isInterrupted()) {
1031: //reset interrupt state
1032: abortNow = false;
1033: Thread.interrupted();
1034: }
1035: } catch (Exception e) {
1036: fBusy = false;
1037: if (abortNow && currentThread.isInterrupted()) {
1038: Thread.interrupted();
1039: }
1040: if (abortNow) {
1041: abortNow = false;
1042: restoreHandlers();
1043: return null;
1044: }
1045: // Consume this exception if the user
1046: // issued an interrupt or an abort.
1047: if (e != ABORT) {
1048: if (!(e instanceof XMLParseException)
1049: && fErrorHandler != null) {
1050: DOMErrorImpl error = new DOMErrorImpl();
1051: error.fException = e;
1052: error.fMessage = e.getMessage();
1053: error.fSeverity = DOMError.SEVERITY_FATAL_ERROR;
1054: fErrorHandler.getErrorHandler().handleError(error);
1055: }
1056: if (DEBUG) {
1057: e.printStackTrace();
1058: }
1059: throw (LSException) DOMUtil.createLSException(
1060: LSException.PARSE_ERR, e).fillInStackTrace();
1061: }
1062: }
1063: Document doc = getDocument();
1064: dropDocumentReferences();
1065: return doc;
1066: }
1067:
1068: private void restoreHandlers() {
1069: fConfiguration.setDocumentHandler(this );
1070: fConfiguration.setDTDHandler(this );
1071: fConfiguration.setDTDContentModelHandler(this );
1072: }
1073:
1074: /**
1075: * Parse an XML document or fragment from a resource identified by an
1076: * <code>LSInput</code> and insert the content into an existing
1077: * document at the position epcified with the <code>contextNode</code>
1078: * and <code>action</code> arguments. When parsing the input stream the
1079: * context node is used for resolving unbound namespace prefixes.
1080: *
1081: * @param is The <code>LSInput</code> from which the source
1082: * document is to be read.
1083: * @param cnode The <code>Node</code> that is used as the context for
1084: * the data that is being parsed.
1085: * @param action This parameter describes which action should be taken
1086: * between the new set of node being inserted and the existing
1087: * children of the context node. The set of possible actions is
1088: * defined above.
1089: * @exception DOMException
1090: * HIERARCHY_REQUEST_ERR: Thrown if this action results in an invalid
1091: * hierarchy (i.e. a Document with more than one document element).
1092: */
1093: public Node parseWithContext(LSInput is, Node cnode, short action)
1094: throws DOMException, LSException {
1095: // REVISIT: need to implement.
1096: throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1097: "Not supported");
1098: }
1099:
1100: /**
1101: * NON-DOM: convert LSInput to XNIInputSource
1102: *
1103: * @param is
1104: * @return
1105: */
1106: XMLInputSource dom2xmlInputSource(LSInput is) {
1107: // need to wrap the LSInput with an XMLInputSource
1108: XMLInputSource xis = null;
1109: // check whether there is a Reader
1110: // according to DOM, we need to treat such reader as "UTF-16".
1111: if (is.getCharacterStream() != null) {
1112: xis = new XMLInputSource(is.getPublicId(),
1113: is.getSystemId(), is.getBaseURI(), is
1114: .getCharacterStream(), "UTF-16");
1115: }
1116: // check whether there is an InputStream
1117: else if (is.getByteStream() != null) {
1118: xis = new XMLInputSource(is.getPublicId(),
1119: is.getSystemId(), is.getBaseURI(), is
1120: .getByteStream(), is.getEncoding());
1121: }
1122: // if there is a string data, use a StringReader
1123: // according to DOM, we need to treat such data as "UTF-16".
1124: else if (is.getStringData() != null
1125: && is.getStringData().length() > 0) {
1126: xis = new XMLInputSource(is.getPublicId(),
1127: is.getSystemId(), is.getBaseURI(),
1128: new StringReader(is.getStringData()), "UTF-16");
1129: }
1130: // otherwise, just use the public/system/base Ids
1131: else if ((is.getSystemId() != null && is.getSystemId().length() > 0)
1132: || (is.getPublicId() != null && is.getPublicId()
1133: .length() > 0)) {
1134: xis = new XMLInputSource(is.getPublicId(),
1135: is.getSystemId(), is.getBaseURI());
1136: } else {
1137: // all inputs are null
1138: if (fErrorHandler != null) {
1139: DOMErrorImpl error = new DOMErrorImpl();
1140: error.fType = "no-input-specified";
1141: error.fMessage = "no-input-specified";
1142: error.fSeverity = DOMError.SEVERITY_FATAL_ERROR;
1143: fErrorHandler.getErrorHandler().handleError(error);
1144: }
1145: throw new LSException(LSException.PARSE_ERR,
1146: "no-input-specified");
1147: }
1148: return xis;
1149: }
1150:
1151: /**
1152: * @see org.w3c.dom.ls.LSParser#getAsync()
1153: */
1154: public boolean getAsync() {
1155: return false;
1156: }
1157:
1158: /**
1159: * @see org.w3c.dom.ls.LSParser#getBusy()
1160: */
1161: public boolean getBusy() {
1162: return fBusy;
1163: }
1164:
1165: /**
1166: * @see org.w3c.dom.ls.LSParser#abort()
1167: */
1168: public void abort() {
1169: // If parse operation is in progress then reset it
1170: if (fBusy) {
1171: fBusy = false;
1172: if (currentThread != null) {
1173: abortNow = true;
1174: fConfiguration.setDocumentHandler(abortHandler);
1175: fConfiguration.setDTDHandler(abortHandler);
1176: fConfiguration.setDTDContentModelHandler(abortHandler);
1177: if (currentThread == Thread.currentThread()) {
1178: throw ABORT;
1179: }
1180: currentThread.interrupt();
1181: }
1182: }
1183: return; // If not busy then this is noop
1184: }
1185:
1186: /**
1187: * The start of an element. If the document specifies the start element
1188: * by using an empty tag, then the startElement method will immediately
1189: * be followed by the endElement method, with no intervening methods.
1190: * Overriding the parent to handle DOM_NAMESPACE_DECLARATIONS=false.
1191: *
1192: * @param element The name of the element.
1193: * @param attributes The element attributes.
1194: * @param augs Additional information that may include infoset augmentations
1195: *
1196: * @throws XNIException Thrown by handler to signal an error.
1197: */
1198: public void startElement(QName element, XMLAttributes attributes,
1199: Augmentations augs) {
1200: // namespace declarations parameter has no effect if namespaces is false.
1201: if (!fNamespaceDeclarations && fNamespaceAware) {
1202: int len = attributes.getLength();
1203: for (int i = len - 1; i >= 0; --i) {
1204: if (XMLSymbols.PREFIX_XMLNS == attributes.getPrefix(i)
1205: || XMLSymbols.PREFIX_XMLNS == attributes
1206: .getQName(i)) {
1207: attributes.removeAttributeAt(i);
1208: }
1209: }
1210: }
1211: super .startElement(element, attributes, augs);
1212: }
1213:
1214: private static final class AbortHandler implements
1215: XMLDocumentHandler, XMLDTDHandler,
1216: XMLDTDContentModelHandler {
1217:
1218: private XMLDocumentSource documentSource;
1219: private XMLDTDContentModelSource dtdContentSource;
1220: private XMLDTDSource dtdSource;
1221:
1222: public void startDocument(XMLLocator locator, String encoding,
1223: NamespaceContext namespaceContext, Augmentations augs)
1224: throws XNIException {
1225: throw ABORT;
1226: }
1227:
1228: public void xmlDecl(String version, String encoding,
1229: String standalone, Augmentations augs)
1230: throws XNIException {
1231: throw ABORT;
1232: }
1233:
1234: public void doctypeDecl(String rootElement, String publicId,
1235: String systemId, Augmentations augs)
1236: throws XNIException {
1237: throw ABORT;
1238: }
1239:
1240: public void comment(XMLString text, Augmentations augs)
1241: throws XNIException {
1242: throw ABORT;
1243: }
1244:
1245: public void processingInstruction(String target,
1246: XMLString data, Augmentations augs) throws XNIException {
1247: throw ABORT;
1248: }
1249:
1250: public void startElement(QName element,
1251: XMLAttributes attributes, Augmentations augs)
1252: throws XNIException {
1253: throw ABORT;
1254: }
1255:
1256: public void emptyElement(QName element,
1257: XMLAttributes attributes, Augmentations augs)
1258: throws XNIException {
1259: throw ABORT;
1260: }
1261:
1262: public void startGeneralEntity(String name,
1263: XMLResourceIdentifier identifier, String encoding,
1264: Augmentations augs) throws XNIException {
1265: throw ABORT;
1266: }
1267:
1268: public void textDecl(String version, String encoding,
1269: Augmentations augs) throws XNIException {
1270: throw ABORT;
1271: }
1272:
1273: public void endGeneralEntity(String name, Augmentations augs)
1274: throws XNIException {
1275: throw ABORT;
1276: }
1277:
1278: public void characters(XMLString text, Augmentations augs)
1279: throws XNIException {
1280: throw ABORT;
1281: }
1282:
1283: public void ignorableWhitespace(XMLString text,
1284: Augmentations augs) throws XNIException {
1285: throw ABORT;
1286: }
1287:
1288: public void endElement(QName element, Augmentations augs)
1289: throws XNIException {
1290: throw ABORT;
1291: }
1292:
1293: public void startCDATA(Augmentations augs) throws XNIException {
1294: throw ABORT;
1295: }
1296:
1297: public void endCDATA(Augmentations augs) throws XNIException {
1298: throw ABORT;
1299: }
1300:
1301: public void endDocument(Augmentations augs) throws XNIException {
1302: throw ABORT;
1303: }
1304:
1305: public void setDocumentSource(XMLDocumentSource source) {
1306: documentSource = source;
1307: }
1308:
1309: public XMLDocumentSource getDocumentSource() {
1310: return documentSource;
1311: }
1312:
1313: public void startDTD(XMLLocator locator,
1314: Augmentations augmentations) throws XNIException {
1315: throw ABORT;
1316: }
1317:
1318: public void startParameterEntity(String name,
1319: XMLResourceIdentifier identifier, String encoding,
1320: Augmentations augmentations) throws XNIException {
1321: throw ABORT;
1322: }
1323:
1324: public void endParameterEntity(String name,
1325: Augmentations augmentations) throws XNIException {
1326: throw ABORT;
1327: }
1328:
1329: public void startExternalSubset(
1330: XMLResourceIdentifier identifier,
1331: Augmentations augmentations) throws XNIException {
1332: throw ABORT;
1333: }
1334:
1335: public void endExternalSubset(Augmentations augmentations)
1336: throws XNIException {
1337: throw ABORT;
1338: }
1339:
1340: public void elementDecl(String name, String contentModel,
1341: Augmentations augmentations) throws XNIException {
1342: throw ABORT;
1343: }
1344:
1345: public void startAttlist(String elementName,
1346: Augmentations augmentations) throws XNIException {
1347: throw ABORT;
1348: }
1349:
1350: public void attributeDecl(String elementName,
1351: String attributeName, String type,
1352: String[] enumeration, String defaultType,
1353: XMLString defaultValue,
1354: XMLString nonNormalizedDefaultValue,
1355: Augmentations augmentations) throws XNIException {
1356: throw ABORT;
1357: }
1358:
1359: public void endAttlist(Augmentations augmentations)
1360: throws XNIException {
1361: throw ABORT;
1362: }
1363:
1364: public void internalEntityDecl(String name, XMLString text,
1365: XMLString nonNormalizedText, Augmentations augmentations)
1366: throws XNIException {
1367: throw ABORT;
1368: }
1369:
1370: public void externalEntityDecl(String name,
1371: XMLResourceIdentifier identifier,
1372: Augmentations augmentations) throws XNIException {
1373: throw ABORT;
1374: }
1375:
1376: public void unparsedEntityDecl(String name,
1377: XMLResourceIdentifier identifier, String notation,
1378: Augmentations augmentations) throws XNIException {
1379: throw ABORT;
1380: }
1381:
1382: public void notationDecl(String name,
1383: XMLResourceIdentifier identifier,
1384: Augmentations augmentations) throws XNIException {
1385: throw ABORT;
1386: }
1387:
1388: public void startConditional(short type,
1389: Augmentations augmentations) throws XNIException {
1390: throw ABORT;
1391: }
1392:
1393: public void ignoredCharacters(XMLString text,
1394: Augmentations augmentations) throws XNIException {
1395: throw ABORT;
1396: }
1397:
1398: public void endConditional(Augmentations augmentations)
1399: throws XNIException {
1400: throw ABORT;
1401: }
1402:
1403: public void endDTD(Augmentations augmentations)
1404: throws XNIException {
1405: throw ABORT;
1406: }
1407:
1408: public void setDTDSource(XMLDTDSource source) {
1409: dtdSource = source;
1410: }
1411:
1412: public XMLDTDSource getDTDSource() {
1413: return dtdSource;
1414: }
1415:
1416: public void startContentModel(String elementName,
1417: Augmentations augmentations) throws XNIException {
1418: throw ABORT;
1419: }
1420:
1421: public void any(Augmentations augmentations)
1422: throws XNIException {
1423: throw ABORT;
1424: }
1425:
1426: public void empty(Augmentations augmentations)
1427: throws XNIException {
1428: throw ABORT;
1429: }
1430:
1431: public void startGroup(Augmentations augmentations)
1432: throws XNIException {
1433: throw ABORT;
1434: }
1435:
1436: public void pcdata(Augmentations augmentations)
1437: throws XNIException {
1438: throw ABORT;
1439: }
1440:
1441: public void element(String elementName,
1442: Augmentations augmentations) throws XNIException {
1443: throw ABORT;
1444: }
1445:
1446: public void separator(short separator,
1447: Augmentations augmentations) throws XNIException {
1448: throw ABORT;
1449: }
1450:
1451: public void occurrence(short occurrence,
1452: Augmentations augmentations) throws XNIException {
1453: throw ABORT;
1454: }
1455:
1456: public void endGroup(Augmentations augmentations)
1457: throws XNIException {
1458: throw ABORT;
1459: }
1460:
1461: public void endContentModel(Augmentations augmentations)
1462: throws XNIException {
1463: throw ABORT;
1464: }
1465:
1466: public void setDTDContentModelSource(
1467: XMLDTDContentModelSource source) {
1468: dtdContentSource = source;
1469: }
1470:
1471: public XMLDTDContentModelSource getDTDContentModelSource() {
1472: return dtdContentSource;
1473: }
1474:
1475: }
1476:
1477: } // class DOMParserImpl
|