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.impl.xs;
0019:
0020: import java.io.BufferedInputStream;
0021: import java.io.File;
0022: import java.io.FileInputStream;
0023: import java.io.FileNotFoundException;
0024: import java.io.IOException;
0025: import java.io.InputStream;
0026: import java.io.Reader;
0027: import java.io.StringReader;
0028: import java.util.ArrayList;
0029: import java.util.Hashtable;
0030: import java.util.Locale;
0031: import java.util.StringTokenizer;
0032: import java.util.Vector;
0033: import java.util.WeakHashMap;
0034:
0035: import org.apache.xerces.dom.DOMErrorImpl;
0036: import org.apache.xerces.dom.DOMMessageFormatter;
0037: import org.apache.xerces.dom.DOMStringListImpl;
0038: import org.apache.xerces.impl.Constants;
0039: import org.apache.xerces.impl.XMLEntityManager;
0040: import org.apache.xerces.impl.XMLErrorReporter;
0041: import org.apache.xerces.impl.dv.InvalidDatatypeValueException;
0042: import org.apache.xerces.impl.xs.models.CMBuilder;
0043: import org.apache.xerces.impl.xs.models.CMNodeFactory;
0044: import org.apache.xerces.impl.xs.traversers.XSDHandler;
0045: import org.apache.xerces.util.DOMEntityResolverWrapper;
0046: import org.apache.xerces.util.DOMErrorHandlerWrapper;
0047: import org.apache.xerces.util.DefaultErrorHandler;
0048: import org.apache.xerces.util.MessageFormatter;
0049: import org.apache.xerces.util.ParserConfigurationSettings;
0050: import org.apache.xerces.util.SymbolTable;
0051: import org.apache.xerces.util.XMLSymbols;
0052: import org.apache.xerces.xni.XNIException;
0053: import org.apache.xerces.xni.grammars.Grammar;
0054: import org.apache.xerces.xni.grammars.XMLGrammarDescription;
0055: import org.apache.xerces.xni.grammars.XMLGrammarLoader;
0056: import org.apache.xerces.xni.grammars.XMLGrammarPool;
0057: import org.apache.xerces.xni.grammars.XSGrammar;
0058: import org.apache.xerces.xni.parser.XMLComponent;
0059: import org.apache.xerces.xni.parser.XMLComponentManager;
0060: import org.apache.xerces.xni.parser.XMLConfigurationException;
0061: import org.apache.xerces.xni.parser.XMLEntityResolver;
0062: import org.apache.xerces.xni.parser.XMLErrorHandler;
0063: import org.apache.xerces.xni.parser.XMLInputSource;
0064: import org.apache.xerces.xs.LSInputList;
0065: import org.apache.xerces.xs.StringList;
0066: import org.apache.xerces.xs.XSLoader;
0067: import org.apache.xerces.xs.XSModel;
0068: import org.w3c.dom.DOMConfiguration;
0069: import org.w3c.dom.DOMError;
0070: import org.w3c.dom.DOMErrorHandler;
0071: import org.w3c.dom.DOMException;
0072: import org.w3c.dom.DOMStringList;
0073: import org.w3c.dom.ls.LSInput;
0074: import org.w3c.dom.ls.LSResourceResolver;
0075: import org.xml.sax.InputSource;
0076:
0077: /**
0078: * This class implements xni.grammars.XMLGrammarLoader.
0079: * It also serves as implementation of xs.XSLoader interface and DOMConfiguration interface.
0080: *
0081: * This class is designed to interact either with a proxy for a user application
0082: * which wants to preparse schemas, or with our own Schema validator.
0083: * It is hoped that none of these "external" classes will therefore need to communicate directly
0084: * with XSDHandler in future.
0085: * <p>This class only knows how to make XSDHandler do its thing.
0086: * The caller must ensure that all its properties (schemaLocation, JAXPSchemaSource
0087: * etc.) have been properly set.
0088: *
0089: * @xerces.internal
0090: *
0091: * @author Neil Graham, IBM
0092: * @version $Id: XMLSchemaLoader.java 521495 2007-03-22 22:12:05Z mrglavas $
0093: */
0094: public class XMLSchemaLoader implements XMLGrammarLoader, XMLComponent,
0095: // XML Component API
0096: XSLoader, DOMConfiguration {
0097:
0098: // Feature identifiers:
0099:
0100: /** Feature identifier: schema full checking*/
0101: protected static final String SCHEMA_FULL_CHECKING = Constants.XERCES_FEATURE_PREFIX
0102: + Constants.SCHEMA_FULL_CHECKING;
0103:
0104: /** Feature identifier: continue after fatal error. */
0105: protected static final String CONTINUE_AFTER_FATAL_ERROR = Constants.XERCES_FEATURE_PREFIX
0106: + Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE;
0107:
0108: /** Feature identifier: allow java encodings to be recognized when parsing schema docs. */
0109: protected static final String ALLOW_JAVA_ENCODINGS = Constants.XERCES_FEATURE_PREFIX
0110: + Constants.ALLOW_JAVA_ENCODINGS_FEATURE;
0111:
0112: /** Feature identifier: standard uri conformant feature. */
0113: protected static final String STANDARD_URI_CONFORMANT_FEATURE = Constants.XERCES_FEATURE_PREFIX
0114: + Constants.STANDARD_URI_CONFORMANT_FEATURE;
0115:
0116: /** Feature identifier: validate annotations. */
0117: protected static final String VALIDATE_ANNOTATIONS = Constants.XERCES_FEATURE_PREFIX
0118: + Constants.VALIDATE_ANNOTATIONS_FEATURE;
0119:
0120: /** Feature: disallow doctype*/
0121: protected static final String DISALLOW_DOCTYPE = Constants.XERCES_FEATURE_PREFIX
0122: + Constants.DISALLOW_DOCTYPE_DECL_FEATURE;
0123:
0124: /** Feature: generate synthetic annotations */
0125: protected static final String GENERATE_SYNTHETIC_ANNOTATIONS = Constants.XERCES_FEATURE_PREFIX
0126: + Constants.GENERATE_SYNTHETIC_ANNOTATIONS_FEATURE;
0127:
0128: /** Feature identifier: honour all schemaLocations */
0129: protected static final String HONOUR_ALL_SCHEMALOCATIONS = Constants.XERCES_FEATURE_PREFIX
0130: + Constants.HONOUR_ALL_SCHEMALOCATIONS_FEATURE;
0131:
0132: protected static final String AUGMENT_PSVI = Constants.XERCES_FEATURE_PREFIX
0133: + Constants.SCHEMA_AUGMENT_PSVI;
0134:
0135: protected static final String PARSER_SETTINGS = Constants.XERCES_FEATURE_PREFIX
0136: + Constants.PARSER_SETTINGS;
0137:
0138: // recognized features:
0139: private static final String[] RECOGNIZED_FEATURES = {
0140: SCHEMA_FULL_CHECKING, AUGMENT_PSVI,
0141: CONTINUE_AFTER_FATAL_ERROR, ALLOW_JAVA_ENCODINGS,
0142: STANDARD_URI_CONFORMANT_FEATURE, DISALLOW_DOCTYPE,
0143: GENERATE_SYNTHETIC_ANNOTATIONS, VALIDATE_ANNOTATIONS,
0144: HONOUR_ALL_SCHEMALOCATIONS };
0145:
0146: // property identifiers
0147:
0148: /** Property identifier: symbol table. */
0149: public static final String SYMBOL_TABLE = Constants.XERCES_PROPERTY_PREFIX
0150: + Constants.SYMBOL_TABLE_PROPERTY;
0151:
0152: /** Property identifier: error reporter. */
0153: public static final String ERROR_REPORTER = Constants.XERCES_PROPERTY_PREFIX
0154: + Constants.ERROR_REPORTER_PROPERTY;
0155:
0156: /** Property identifier: error handler. */
0157: protected static final String ERROR_HANDLER = Constants.XERCES_PROPERTY_PREFIX
0158: + Constants.ERROR_HANDLER_PROPERTY;
0159:
0160: /** Property identifier: entity resolver. */
0161: public static final String ENTITY_RESOLVER = Constants.XERCES_PROPERTY_PREFIX
0162: + Constants.ENTITY_RESOLVER_PROPERTY;
0163:
0164: /** Property identifier: grammar pool. */
0165: public static final String XMLGRAMMAR_POOL = Constants.XERCES_PROPERTY_PREFIX
0166: + Constants.XMLGRAMMAR_POOL_PROPERTY;
0167:
0168: /** Property identifier: schema location. */
0169: protected static final String SCHEMA_LOCATION = Constants.XERCES_PROPERTY_PREFIX
0170: + Constants.SCHEMA_LOCATION;
0171:
0172: /** Property identifier: no namespace schema location. */
0173: protected static final String SCHEMA_NONS_LOCATION = Constants.XERCES_PROPERTY_PREFIX
0174: + Constants.SCHEMA_NONS_LOCATION;
0175:
0176: /** Property identifier: JAXP schema source. */
0177: protected static final String JAXP_SCHEMA_SOURCE = Constants.JAXP_PROPERTY_PREFIX
0178: + Constants.SCHEMA_SOURCE;
0179:
0180: protected static final String SECURITY_MANAGER = Constants.XERCES_PROPERTY_PREFIX
0181: + Constants.SECURITY_MANAGER_PROPERTY;
0182:
0183: protected static final String ENTITY_MANAGER = Constants.XERCES_PROPERTY_PREFIX
0184: + Constants.ENTITY_MANAGER_PROPERTY;
0185:
0186: // recognized properties
0187: private static final String[] RECOGNIZED_PROPERTIES = {
0188: ENTITY_MANAGER, SYMBOL_TABLE, ERROR_REPORTER,
0189: ERROR_HANDLER, ENTITY_RESOLVER, XMLGRAMMAR_POOL,
0190: SCHEMA_LOCATION, SCHEMA_NONS_LOCATION, JAXP_SCHEMA_SOURCE,
0191: SECURITY_MANAGER };
0192:
0193: // Data
0194:
0195: // features and properties
0196: private ParserConfigurationSettings fLoaderConfig = new ParserConfigurationSettings();
0197: private XMLErrorReporter fErrorReporter = new XMLErrorReporter();
0198: private XMLEntityManager fEntityManager = null;
0199: private XMLEntityResolver fUserEntityResolver = null;
0200: private XMLGrammarPool fGrammarPool = null;
0201: private String fExternalSchemas = null;
0202: private String fExternalNoNSSchema = null;
0203: // JAXP property: schema source
0204: private Object fJAXPSource = null;
0205: // is Schema Full Checking enabled
0206: private boolean fIsCheckedFully = false;
0207: // boolean that tells whether we've tested the JAXP property.
0208: private boolean fJAXPProcessed = false;
0209: // if features/properties has not been changed, the value of this attribute is "false"
0210: private boolean fSettingsChanged = true;
0211:
0212: // xml schema parsing
0213: private XSDHandler fSchemaHandler;
0214: private XSGrammarBucket fGrammarBucket;
0215: private XSDeclarationPool fDeclPool = null;
0216: private SubstitutionGroupHandler fSubGroupHandler;
0217: private CMBuilder fCMBuilder;
0218: private XSDDescription fXSDDescription = new XSDDescription();
0219:
0220: private WeakHashMap fJAXPCache;
0221: private Locale fLocale = Locale.getDefault();
0222:
0223: // XSLoader attributes
0224: private DOMStringList fRecognizedParameters = null;
0225:
0226: /** DOM L3 error handler */
0227: private DOMErrorHandlerWrapper fErrorHandler = null;
0228:
0229: /** DOM L3 resource resolver */
0230: private DOMEntityResolverWrapper fResourceResolver = null;
0231:
0232: // default constructor. Create objects we absolutely need:
0233: public XMLSchemaLoader() {
0234: this (new SymbolTable(), null, new XMLEntityManager(), null,
0235: null, null);
0236: }
0237:
0238: public XMLSchemaLoader(SymbolTable symbolTable) {
0239: this (symbolTable, null, new XMLEntityManager(), null, null,
0240: null);
0241: }
0242:
0243: /**
0244: * This constractor is used by the XMLSchemaValidator. Additional properties, i.e. XMLEntityManager,
0245: * will be passed during reset(XMLComponentManager).
0246: * @param errorReporter
0247: * @param grammarBucket
0248: * @param sHandler
0249: * @param builder
0250: */
0251: XMLSchemaLoader(XMLErrorReporter errorReporter,
0252: XSGrammarBucket grammarBucket,
0253: SubstitutionGroupHandler sHandler, CMBuilder builder) {
0254: this (null, errorReporter, null, grammarBucket, sHandler,
0255: builder);
0256: }
0257:
0258: XMLSchemaLoader(SymbolTable symbolTable,
0259: XMLErrorReporter errorReporter,
0260: XMLEntityManager entityResolver,
0261: XSGrammarBucket grammarBucket,
0262: SubstitutionGroupHandler sHandler, CMBuilder builder) {
0263:
0264: // store properties and features in configuration
0265: fLoaderConfig.addRecognizedFeatures(RECOGNIZED_FEATURES);
0266: fLoaderConfig.addRecognizedProperties(RECOGNIZED_PROPERTIES);
0267: if (symbolTable != null) {
0268: fLoaderConfig.setProperty(SYMBOL_TABLE, symbolTable);
0269: }
0270:
0271: if (errorReporter == null) {
0272: errorReporter = new XMLErrorReporter();
0273: errorReporter.setLocale(fLocale);
0274: errorReporter.setProperty(ERROR_HANDLER,
0275: new DefaultErrorHandler());
0276:
0277: }
0278: fErrorReporter = errorReporter;
0279: // make sure error reporter knows about schemas...
0280: if (fErrorReporter
0281: .getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN) == null) {
0282: fErrorReporter.putMessageFormatter(
0283: XSMessageFormatter.SCHEMA_DOMAIN,
0284: new XSMessageFormatter());
0285: }
0286: fLoaderConfig.setProperty(ERROR_REPORTER, fErrorReporter);
0287: fEntityManager = entityResolver;
0288: // entity manager is null if XMLSchemaValidator creates the loader
0289: if (fEntityManager != null) {
0290: fLoaderConfig.setProperty(ENTITY_MANAGER, fEntityManager);
0291: }
0292:
0293: // by default augment PSVI (i.e. don't use declaration pool)
0294: fLoaderConfig.setFeature(AUGMENT_PSVI, true);
0295:
0296: if (grammarBucket == null) {
0297: grammarBucket = new XSGrammarBucket();
0298: }
0299: fGrammarBucket = grammarBucket;
0300: if (sHandler == null) {
0301: sHandler = new SubstitutionGroupHandler(fGrammarBucket);
0302: }
0303: fSubGroupHandler = sHandler;
0304:
0305: //get an instance of the CMNodeFactory */
0306: CMNodeFactory nodeFactory = new CMNodeFactory();
0307:
0308: if (builder == null) {
0309: builder = new CMBuilder(nodeFactory);
0310: }
0311: fCMBuilder = builder;
0312: fSchemaHandler = new XSDHandler(fGrammarBucket);
0313: fDeclPool = new XSDeclarationPool();
0314: fJAXPCache = new WeakHashMap();
0315:
0316: fSettingsChanged = true;
0317: }
0318:
0319: /**
0320: * Returns a list of feature identifiers that are recognized by
0321: * this XMLGrammarLoader. This method may return null if no features
0322: * are recognized.
0323: */
0324: public String[] getRecognizedFeatures() {
0325: return (String[]) (RECOGNIZED_FEATURES.clone());
0326: } // getRecognizedFeatures(): String[]
0327:
0328: /**
0329: * Returns the state of a feature.
0330: *
0331: * @param featureId The feature identifier.
0332: *
0333: * @throws XMLConfigurationException Thrown on configuration error.
0334: */
0335: public boolean getFeature(String featureId)
0336: throws XMLConfigurationException {
0337: return fLoaderConfig.getFeature(featureId);
0338: } // getFeature (String): boolean
0339:
0340: /**
0341: * Sets the state of a feature.
0342: *
0343: * @param featureId The feature identifier.
0344: * @param state The state of the feature.
0345: *
0346: * @throws XMLConfigurationException Thrown when a feature is not
0347: * recognized or cannot be set.
0348: */
0349: public void setFeature(String featureId, boolean state)
0350: throws XMLConfigurationException {
0351: fSettingsChanged = true;
0352: if (featureId.equals(CONTINUE_AFTER_FATAL_ERROR)) {
0353: fErrorReporter
0354: .setFeature(CONTINUE_AFTER_FATAL_ERROR, state);
0355: } else if (featureId.equals(GENERATE_SYNTHETIC_ANNOTATIONS)) {
0356: fSchemaHandler.setGenerateSyntheticAnnotations(state);
0357: }
0358: fLoaderConfig.setFeature(featureId, state);
0359: } // setFeature(String, boolean)
0360:
0361: /**
0362: * Returns a list of property identifiers that are recognized by
0363: * this XMLGrammarLoader. This method may return null if no properties
0364: * are recognized.
0365: */
0366: public String[] getRecognizedProperties() {
0367: return (String[]) (RECOGNIZED_PROPERTIES.clone());
0368: } // getRecognizedProperties(): String[]
0369:
0370: /**
0371: * Returns the state of a property.
0372: *
0373: * @param propertyId The property identifier.
0374: *
0375: * @throws XMLConfigurationException Thrown on configuration error.
0376: */
0377: public Object getProperty(String propertyId)
0378: throws XMLConfigurationException {
0379: return fLoaderConfig.getProperty(propertyId);
0380: } // getProperty(String): Object
0381:
0382: /**
0383: * Sets the state of a property.
0384: *
0385: * @param propertyId The property identifier.
0386: * @param state The state of the property.
0387: *
0388: * @throws XMLConfigurationException Thrown when a property is not
0389: * recognized or cannot be set.
0390: */
0391: public void setProperty(String propertyId, Object state)
0392: throws XMLConfigurationException {
0393: fSettingsChanged = true;
0394: fLoaderConfig.setProperty(propertyId, state);
0395: if (propertyId.equals(JAXP_SCHEMA_SOURCE)) {
0396: fJAXPSource = state;
0397: fJAXPProcessed = false;
0398: } else if (propertyId.equals(XMLGRAMMAR_POOL)) {
0399: fGrammarPool = (XMLGrammarPool) state;
0400: } else if (propertyId.equals(SCHEMA_LOCATION)) {
0401: fExternalSchemas = (String) state;
0402: } else if (propertyId.equals(SCHEMA_NONS_LOCATION)) {
0403: fExternalNoNSSchema = (String) state;
0404: } else if (propertyId.equals(ENTITY_RESOLVER)) {
0405: fEntityManager.setProperty(ENTITY_RESOLVER, state);
0406: } else if (propertyId.equals(ERROR_REPORTER)) {
0407: fErrorReporter = (XMLErrorReporter) state;
0408: if (fErrorReporter
0409: .getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN) == null) {
0410: fErrorReporter.putMessageFormatter(
0411: XSMessageFormatter.SCHEMA_DOMAIN,
0412: new XSMessageFormatter());
0413: }
0414: }
0415: } // setProperty(String, Object)
0416:
0417: /**
0418: * Set the locale to use for messages.
0419: *
0420: * @param locale The locale object to use for localization of messages.
0421: *
0422: * @exception XNIException Thrown if the parser does not support the
0423: * specified locale.
0424: */
0425: public void setLocale(Locale locale) {
0426: fLocale = locale;
0427: fErrorReporter.setLocale(locale);
0428: } // setLocale(Locale)
0429:
0430: /** Return the Locale the XMLGrammarLoader is using. */
0431: public Locale getLocale() {
0432: return fLocale;
0433: } // getLocale(): Locale
0434:
0435: /**
0436: * Sets the error handler.
0437: *
0438: * @param errorHandler The error handler.
0439: */
0440: public void setErrorHandler(XMLErrorHandler errorHandler) {
0441: fErrorReporter.setProperty(ERROR_HANDLER, errorHandler);
0442: } // setErrorHandler(XMLErrorHandler)
0443:
0444: /** Returns the registered error handler. */
0445: public XMLErrorHandler getErrorHandler() {
0446: return fErrorReporter.getErrorHandler();
0447: } // getErrorHandler(): XMLErrorHandler
0448:
0449: /**
0450: * Sets the entity resolver.
0451: *
0452: * @param entityResolver The new entity resolver.
0453: */
0454: public void setEntityResolver(XMLEntityResolver entityResolver) {
0455: fUserEntityResolver = entityResolver;
0456: fLoaderConfig.setProperty(ENTITY_RESOLVER, entityResolver);
0457: fEntityManager.setProperty(ENTITY_RESOLVER, entityResolver);
0458: } // setEntityResolver(XMLEntityResolver)
0459:
0460: /** Returns the registered entity resolver. */
0461: public XMLEntityResolver getEntityResolver() {
0462: return fUserEntityResolver;
0463: } // getEntityResolver(): XMLEntityResolver
0464:
0465: /**
0466: * Returns a Grammar object by parsing the contents of the
0467: * entities pointed to by sources.
0468: *
0469: * @param source the locations of the entity which forms
0470: * the staring point of the grammars to be constructed
0471: * @throws IOException when a problem is encounted reading the entity
0472: * @throws XNIException when a condition arises (such as a FatalError) that requires parsing
0473: * of the entity be terminated
0474: */
0475: public void loadGrammar(XMLInputSource source[])
0476: throws IOException, XNIException {
0477: int numSource = source.length;
0478: for (int i = 0; i < numSource; ++i) {
0479: loadGrammar(source[i]);
0480: }
0481: }
0482:
0483: /**
0484: * Returns a Grammar object by parsing the contents of the
0485: * entity pointed to by source.
0486: *
0487: * @param source the location of the entity which forms
0488: * the starting point of the grammar to be constructed.
0489: * @throws IOException When a problem is encountered reading the entity
0490: * XNIException When a condition arises (such as a FatalError) that requires parsing
0491: * of the entity be terminated.
0492: */
0493: public Grammar loadGrammar(XMLInputSource source)
0494: throws IOException, XNIException {
0495:
0496: // REVISIT: this method should have a namespace parameter specified by
0497: // user. In this case we can easily detect if a schema asked to be loaded
0498: // is already in the local cache.
0499:
0500: reset(fLoaderConfig);
0501: fSettingsChanged = false;
0502: XSDDescription desc = new XSDDescription();
0503: desc.fContextType = XSDDescription.CONTEXT_PREPARSE;
0504: desc.setBaseSystemId(source.getBaseSystemId());
0505: desc.setLiteralSystemId(source.getSystemId());
0506: // none of the other fields make sense for preparsing
0507: Hashtable locationPairs = new Hashtable();
0508: // Process external schema location properties.
0509: // We don't call tokenizeSchemaLocationStr here, because we also want
0510: // to check whether the values are valid URI.
0511: processExternalHints(fExternalSchemas, fExternalNoNSSchema,
0512: locationPairs, fErrorReporter);
0513: SchemaGrammar grammar = loadSchema(desc, source, locationPairs);
0514:
0515: if (grammar != null && fGrammarPool != null) {
0516: fGrammarPool.cacheGrammars(
0517: XMLGrammarDescription.XML_SCHEMA, fGrammarBucket
0518: .getGrammars());
0519: // NOTE: we only need to verify full checking in case the schema was not provided via JAXP
0520: // since full checking already verified for all JAXP schemas
0521: if (fIsCheckedFully && fJAXPCache.get(grammar) != grammar) {
0522: XSConstraints.fullSchemaChecking(fGrammarBucket,
0523: fSubGroupHandler, fCMBuilder, fErrorReporter);
0524: }
0525: }
0526: return grammar;
0527: } // loadGrammar(XMLInputSource): Grammar
0528:
0529: /**
0530: * This method is called either from XMLGrammarLoader.loadGrammar or from XMLSchemaValidator.
0531: * Note: in either case, the EntityManager (or EntityResolvers) are not going to be invoked
0532: * to resolve the location of the schema in XSDDescription
0533: * @param desc
0534: * @param source
0535: * @param locationPairs
0536: * @return An XML Schema grammar
0537: * @throws IOException
0538: * @throws XNIException
0539: */
0540: SchemaGrammar loadSchema(XSDDescription desc,
0541: XMLInputSource source, Hashtable locationPairs)
0542: throws IOException, XNIException {
0543:
0544: // this should only be done once per invocation of this object;
0545: // unless application alters JAXPSource in the mean time.
0546: if (!fJAXPProcessed) {
0547: processJAXPSchemaSource(locationPairs);
0548: }
0549: SchemaGrammar grammar = fSchemaHandler.parseSchema(source,
0550: desc, locationPairs);
0551:
0552: return grammar;
0553: } // loadSchema(XSDDescription, XMLInputSource): SchemaGrammar
0554:
0555: /**
0556: * This method tries to resolve location of the given schema.
0557: * The loader stores the namespace/location pairs in a hashtable (use "" as the
0558: * namespace of absent namespace). When resolving an entity, loader first tries
0559: * to find in the hashtable whether there is a value for that namespace,
0560: * if so, pass that location value to the user-defined entity resolver.
0561: *
0562: * @param desc
0563: * @param locationPairs
0564: * @param entityResolver
0565: * @return the XMLInputSource
0566: * @throws IOException
0567: */
0568: public static XMLInputSource resolveDocument(XSDDescription desc,
0569: Hashtable locationPairs, XMLEntityResolver entityResolver)
0570: throws IOException {
0571: String loc = null;
0572: // we consider the schema location properties for import
0573: if (desc.getContextType() == XSDDescription.CONTEXT_IMPORT
0574: || desc.fromInstance()) {
0575: // use empty string as the key for absent namespace
0576: String namespace = desc.getTargetNamespace();
0577: String ns = namespace == null ? XMLSymbols.EMPTY_STRING
0578: : namespace;
0579: // get the location hint for that namespace
0580: LocationArray tempLA = (LocationArray) locationPairs
0581: .get(ns);
0582: if (tempLA != null)
0583: loc = tempLA.getFirstLocation();
0584: }
0585:
0586: // if it's not import, or if the target namespace is not set
0587: // in the schema location properties, use location hint
0588: if (loc == null) {
0589: String[] hints = desc.getLocationHints();
0590: if (hints != null && hints.length > 0)
0591: loc = hints[0];
0592: }
0593:
0594: String expandedLoc = XMLEntityManager.expandSystemId(loc, desc
0595: .getBaseSystemId(), false);
0596: desc.setLiteralSystemId(loc);
0597: desc.setExpandedSystemId(expandedLoc);
0598: return entityResolver.resolveEntity(desc);
0599: }
0600:
0601: // add external schema locations to the location pairs
0602: public static void processExternalHints(String sl, String nsl,
0603: Hashtable locations, XMLErrorReporter er) {
0604: if (sl != null) {
0605: try {
0606: // get the attribute decl for xsi:schemaLocation
0607: // because external schema location property has the same syntax
0608: // as xsi:schemaLocation
0609: XSAttributeDecl attrDecl = SchemaGrammar.SG_XSI
0610: .getGlobalAttributeDecl(SchemaSymbols.XSI_SCHEMALOCATION);
0611: // validation the string value to get the list of URI's
0612: attrDecl.fType.validate(sl, null, null);
0613: if (!tokenizeSchemaLocationStr(sl, locations)) {
0614: // report warning (odd number of items)
0615: er.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
0616: "SchemaLocation", new Object[] { sl },
0617: XMLErrorReporter.SEVERITY_WARNING);
0618: }
0619: } catch (InvalidDatatypeValueException ex) {
0620: // report warning (not list of URI's)
0621: er.reportError(XSMessageFormatter.SCHEMA_DOMAIN, ex
0622: .getKey(), ex.getArgs(),
0623: XMLErrorReporter.SEVERITY_WARNING);
0624: }
0625: }
0626:
0627: if (nsl != null) {
0628: try {
0629: // similarly for no ns schema location property
0630: XSAttributeDecl attrDecl = SchemaGrammar.SG_XSI
0631: .getGlobalAttributeDecl(SchemaSymbols.XSI_NONAMESPACESCHEMALOCATION);
0632: attrDecl.fType.validate(nsl, null, null);
0633: LocationArray la = ((LocationArray) locations
0634: .get(XMLSymbols.EMPTY_STRING));
0635: if (la == null) {
0636: la = new LocationArray();
0637: locations.put(XMLSymbols.EMPTY_STRING, la);
0638: }
0639: la.addLocation(nsl);
0640: } catch (InvalidDatatypeValueException ex) {
0641: // report warning (not a URI)
0642: er.reportError(XSMessageFormatter.SCHEMA_DOMAIN, ex
0643: .getKey(), ex.getArgs(),
0644: XMLErrorReporter.SEVERITY_WARNING);
0645: }
0646: }
0647: }
0648:
0649: // this method takes a SchemaLocation string.
0650: // If an error is encountered, false is returned;
0651: // otherwise, true is returned. In either case, locations
0652: // is augmented to include as many tokens as possible.
0653: // @param schemaStr The schemaLocation string to tokenize
0654: // @param locations Hashtable mapping namespaces to LocationArray objects holding lists of locaitons
0655: // @return true if no problems; false if string could not be tokenized
0656: public static boolean tokenizeSchemaLocationStr(String schemaStr,
0657: Hashtable locations) {
0658: if (schemaStr != null) {
0659: StringTokenizer t = new StringTokenizer(schemaStr,
0660: " \n\t\r");
0661: String namespace, location;
0662: while (t.hasMoreTokens()) {
0663: namespace = t.nextToken();
0664: if (!t.hasMoreTokens()) {
0665: return false; // error!
0666: }
0667: location = t.nextToken();
0668: LocationArray la = ((LocationArray) locations
0669: .get(namespace));
0670: if (la == null) {
0671: la = new LocationArray();
0672: locations.put(namespace, la);
0673: }
0674: la.addLocation(location);
0675: }
0676: }
0677: return true;
0678: } // tokenizeSchemaLocation(String, Hashtable): boolean
0679:
0680: /**
0681: * Translate the various JAXP SchemaSource property types to XNI
0682: * XMLInputSource. Valid types are: String, org.xml.sax.InputSource,
0683: * InputStream, File, or Object[] of any of previous types.
0684: * REVISIT: the JAXP 1.2 spec is less than clear as to whether this property
0685: * should be available to imported schemas. I have assumed
0686: * that it should. - NG
0687: * Note: all JAXP schema files will be checked for full-schema validity if the feature was set up
0688: *
0689: */
0690: private void processJAXPSchemaSource(Hashtable locationPairs)
0691: throws IOException {
0692: fJAXPProcessed = true;
0693: if (fJAXPSource == null) {
0694: return;
0695: }
0696:
0697: Class componentType = fJAXPSource.getClass().getComponentType();
0698: XMLInputSource xis = null;
0699: String sid = null;
0700: if (componentType == null) {
0701: // Not an array
0702: if (fJAXPSource instanceof InputStream
0703: || fJAXPSource instanceof InputSource) {
0704: SchemaGrammar g = (SchemaGrammar) fJAXPCache
0705: .get(fJAXPSource);
0706: if (g != null) {
0707: fGrammarBucket.putGrammar(g);
0708: return;
0709: }
0710: }
0711: fXSDDescription.reset();
0712: xis = xsdToXMLInputSource(fJAXPSource);
0713: sid = xis.getSystemId();
0714: fXSDDescription.fContextType = XSDDescription.CONTEXT_PREPARSE;
0715: if (sid != null) {
0716: fXSDDescription.setBaseSystemId(xis.getBaseSystemId());
0717: fXSDDescription.setLiteralSystemId(sid);
0718: fXSDDescription.setExpandedSystemId(sid);
0719: fXSDDescription.fLocationHints = new String[] { sid };
0720: }
0721: SchemaGrammar g = loadSchema(fXSDDescription, xis,
0722: locationPairs);
0723: // it is possible that we won't be able to resolve JAXP schema-source location
0724: if (g != null) {
0725: if (fJAXPSource instanceof InputStream
0726: || fJAXPSource instanceof InputSource) {
0727: fJAXPCache.put(fJAXPSource, g);
0728: if (fIsCheckedFully) {
0729: XSConstraints.fullSchemaChecking(
0730: fGrammarBucket, fSubGroupHandler,
0731: fCMBuilder, fErrorReporter);
0732: }
0733: }
0734: fGrammarBucket.putGrammar(g);
0735: }
0736: return;
0737: } else if ((componentType != Object.class)
0738: && (componentType != String.class)
0739: && (componentType != File.class)
0740: && (componentType != InputStream.class)
0741: && (componentType != InputSource.class)
0742: && !File.class.isAssignableFrom(componentType)
0743: && !InputStream.class.isAssignableFrom(componentType)
0744: && !InputSource.class.isAssignableFrom(componentType)
0745: && !componentType.isInterface()) {
0746: // Not an Object[], String[], File[], InputStream[], InputSource[]
0747: MessageFormatter mf = fErrorReporter
0748: .getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN);
0749: throw new XMLConfigurationException(
0750: XMLConfigurationException.NOT_SUPPORTED, mf
0751: .formatMessage(fErrorReporter.getLocale(),
0752: "jaxp12-schema-source-type.2",
0753: new Object[] { componentType
0754: .getName() }));
0755: }
0756:
0757: // JAXP spec. allow []s of type String, File, InputStream,
0758: // InputSource also, apart from [] of type Object.
0759: Object[] objArr = (Object[]) fJAXPSource;
0760: // make local vector for storing target namespaces of schemasources specified in object arrays.
0761: ArrayList jaxpSchemaSourceNamespaces = new ArrayList();
0762: for (int i = 0; i < objArr.length; i++) {
0763: if (objArr[i] instanceof InputStream
0764: || objArr[i] instanceof InputSource) {
0765: SchemaGrammar g = (SchemaGrammar) fJAXPCache
0766: .get(objArr[i]);
0767: if (g != null) {
0768: fGrammarBucket.putGrammar(g);
0769: continue;
0770: }
0771: }
0772: fXSDDescription.reset();
0773: xis = xsdToXMLInputSource(objArr[i]);
0774: sid = xis.getSystemId();
0775: fXSDDescription.fContextType = XSDDescription.CONTEXT_PREPARSE;
0776: if (sid != null) {
0777: fXSDDescription.setBaseSystemId(xis.getBaseSystemId());
0778: fXSDDescription.setLiteralSystemId(sid);
0779: fXSDDescription.setExpandedSystemId(sid);
0780: fXSDDescription.fLocationHints = new String[] { sid };
0781: }
0782: String targetNamespace = null;
0783: // load schema
0784: SchemaGrammar grammar = fSchemaHandler.parseSchema(xis,
0785: fXSDDescription, locationPairs);
0786:
0787: if (fIsCheckedFully) {
0788: XSConstraints.fullSchemaChecking(fGrammarBucket,
0789: fSubGroupHandler, fCMBuilder, fErrorReporter);
0790: }
0791: if (grammar != null) {
0792: targetNamespace = grammar.getTargetNamespace();
0793: if (jaxpSchemaSourceNamespaces
0794: .contains(targetNamespace)) {
0795: // when an array of objects is passed it is illegal to have two schemas that share same namespace.
0796: MessageFormatter mf = fErrorReporter
0797: .getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN);
0798: throw new java.lang.IllegalArgumentException(mf
0799: .formatMessage(fErrorReporter.getLocale(),
0800: "jaxp12-schema-source-ns", null));
0801: } else {
0802: jaxpSchemaSourceNamespaces.add(targetNamespace);
0803: }
0804: if (objArr[i] instanceof InputStream
0805: || objArr[i] instanceof InputSource) {
0806: fJAXPCache.put(objArr[i], grammar);
0807: }
0808: fGrammarBucket.putGrammar(grammar);
0809: } else {
0810: //REVISIT: What should be the acutal behavior if grammar can't be loaded as specified in schema source?
0811: }
0812: }
0813: }//processJAXPSchemaSource
0814:
0815: private XMLInputSource xsdToXMLInputSource(Object val) {
0816: if (val instanceof String) {
0817: // String value is treated as a URI that is passed through the
0818: // EntityResolver
0819: String loc = (String) val;
0820: fXSDDescription.reset();
0821: fXSDDescription.setValues(null, loc, null, null);
0822: XMLInputSource xis = null;
0823: try {
0824: xis = fEntityManager.resolveEntity(fXSDDescription);
0825: } catch (IOException ex) {
0826: fErrorReporter.reportError(
0827: XSMessageFormatter.SCHEMA_DOMAIN,
0828: "schema_reference.4", new Object[] { loc },
0829: XMLErrorReporter.SEVERITY_ERROR);
0830: }
0831: if (xis == null) {
0832: // REVISIT: can this happen?
0833: // Treat value as a URI and pass in as systemId
0834: return new XMLInputSource(null, loc, null);
0835: }
0836: return xis;
0837: } else if (val instanceof InputSource) {
0838: return saxToXMLInputSource((InputSource) val);
0839: } else if (val instanceof InputStream) {
0840: return new XMLInputSource(null, null, null,
0841: (InputStream) val, null);
0842: } else if (val instanceof File) {
0843: File file = (File) val;
0844: InputStream is = null;
0845: try {
0846: is = new BufferedInputStream(new FileInputStream(file));
0847: } catch (FileNotFoundException ex) {
0848: fErrorReporter.reportError(
0849: XSMessageFormatter.SCHEMA_DOMAIN,
0850: "schema_reference.4", new Object[] { file
0851: .toString() },
0852: XMLErrorReporter.SEVERITY_ERROR);
0853: }
0854: return new XMLInputSource(null, null, null, is, null);
0855: }
0856: MessageFormatter mf = fErrorReporter
0857: .getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN);
0858: throw new XMLConfigurationException(
0859: XMLConfigurationException.NOT_SUPPORTED,
0860: mf.formatMessage(fErrorReporter.getLocale(),
0861: "jaxp12-schema-source-type.1",
0862: new Object[] { val != null ? val.getClass()
0863: .getName() : "null" }));
0864: }
0865:
0866: //Convert a SAX InputSource to an equivalent XNI XMLInputSource
0867:
0868: private static XMLInputSource saxToXMLInputSource(InputSource sis) {
0869: String publicId = sis.getPublicId();
0870: String systemId = sis.getSystemId();
0871:
0872: Reader charStream = sis.getCharacterStream();
0873: if (charStream != null) {
0874: return new XMLInputSource(publicId, systemId, null,
0875: charStream, null);
0876: }
0877:
0878: InputStream byteStream = sis.getByteStream();
0879: if (byteStream != null) {
0880: return new XMLInputSource(publicId, systemId, null,
0881: byteStream, sis.getEncoding());
0882: }
0883:
0884: return new XMLInputSource(publicId, systemId, null);
0885: }
0886:
0887: static class LocationArray {
0888:
0889: int length;
0890: String[] locations = new String[2];
0891:
0892: public void resize(int oldLength, int newLength) {
0893: String[] temp = new String[newLength];
0894: System.arraycopy(locations, 0, temp, 0, Math.min(oldLength,
0895: newLength));
0896: locations = temp;
0897: length = Math.min(oldLength, newLength);
0898: }
0899:
0900: public void addLocation(String location) {
0901: if (length >= locations.length) {
0902: resize(length, Math.max(1, length * 2));
0903: }
0904: locations[length++] = location;
0905: }//setLocation()
0906:
0907: public String[] getLocationArray() {
0908: if (length < locations.length) {
0909: resize(locations.length, length);
0910: }
0911: return locations;
0912: }//getLocationArray()
0913:
0914: public String getFirstLocation() {
0915: return length > 0 ? locations[0] : null;
0916: }
0917:
0918: public int getLength() {
0919: return length;
0920: }
0921:
0922: } //locationArray
0923:
0924: /* (non-Javadoc)
0925: * @see org.apache.xerces.xni.parser.XMLComponent#getFeatureDefault(java.lang.String)
0926: */
0927: public Boolean getFeatureDefault(String featureId) {
0928: if (featureId.equals(AUGMENT_PSVI)) {
0929: return Boolean.TRUE;
0930: }
0931: return null;
0932: }
0933:
0934: /* (non-Javadoc)
0935: * @see org.apache.xerces.xni.parser.XMLComponent#getPropertyDefault(java.lang.String)
0936: */
0937: public Object getPropertyDefault(String propertyId) {
0938: // TODO Auto-generated method stub
0939: return null;
0940: }
0941:
0942: /* (non-Javadoc)
0943: * @see org.apache.xerces.xni.parser.XMLComponent#reset(org.apache.xerces.xni.parser.XMLComponentManager)
0944: */
0945: public void reset(XMLComponentManager componentManager)
0946: throws XMLConfigurationException {
0947:
0948: fGrammarBucket.reset();
0949:
0950: fSubGroupHandler.reset();
0951:
0952: if (!fSettingsChanged
0953: || !parserSettingsUpdated(componentManager)) {
0954: // need to reprocess JAXP schema sources
0955: fJAXPProcessed = false;
0956: // reinitialize grammar bucket
0957: initGrammarBucket();
0958: return;
0959: }
0960:
0961: // get registered entity manager to be able to resolve JAXP schema-source property:
0962: // Note: in case XMLSchemaValidator has created the loader,
0963: // the entity manager property is null
0964: fEntityManager = (XMLEntityManager) componentManager
0965: .getProperty(ENTITY_MANAGER);
0966:
0967: // get the error reporter
0968: fErrorReporter = (XMLErrorReporter) componentManager
0969: .getProperty(ERROR_REPORTER);
0970:
0971: boolean psvi = true;
0972: try {
0973: psvi = componentManager.getFeature(AUGMENT_PSVI);
0974: } catch (XMLConfigurationException e) {
0975: psvi = false;
0976: }
0977:
0978: if (!psvi) {
0979: fDeclPool.reset();
0980: fCMBuilder.setDeclPool(fDeclPool);
0981: fSchemaHandler.setDeclPool(fDeclPool);
0982: } else {
0983: fCMBuilder.setDeclPool(null);
0984: fSchemaHandler.setDeclPool(null);
0985: }
0986:
0987: // get schema location properties
0988: try {
0989: fExternalSchemas = (String) componentManager
0990: .getProperty(SCHEMA_LOCATION);
0991: fExternalNoNSSchema = (String) componentManager
0992: .getProperty(SCHEMA_NONS_LOCATION);
0993: } catch (XMLConfigurationException e) {
0994: fExternalSchemas = null;
0995: fExternalNoNSSchema = null;
0996: }
0997: // get JAXP sources if available
0998: try {
0999: fJAXPSource = componentManager
1000: .getProperty(JAXP_SCHEMA_SOURCE);
1001: fJAXPProcessed = false;
1002:
1003: } catch (XMLConfigurationException e) {
1004: fJAXPSource = null;
1005: fJAXPProcessed = false;
1006: }
1007:
1008: // clear grammars, and put the one for schema namespace there
1009: try {
1010: fGrammarPool = (XMLGrammarPool) componentManager
1011: .getProperty(XMLGRAMMAR_POOL);
1012: } catch (XMLConfigurationException e) {
1013: fGrammarPool = null;
1014: }
1015: initGrammarBucket();
1016: // get continue-after-fatal-error feature
1017: try {
1018: boolean fatalError = componentManager
1019: .getFeature(CONTINUE_AFTER_FATAL_ERROR);
1020: fErrorReporter.setFeature(CONTINUE_AFTER_FATAL_ERROR,
1021: fatalError);
1022: } catch (XMLConfigurationException e) {
1023: }
1024: // set full validation to false
1025: try {
1026: fIsCheckedFully = componentManager
1027: .getFeature(SCHEMA_FULL_CHECKING);
1028: } catch (XMLConfigurationException e) {
1029: fIsCheckedFully = false;
1030: }
1031: // get generate-synthetic-annotations feature
1032: try {
1033: fSchemaHandler
1034: .setGenerateSyntheticAnnotations(componentManager
1035: .getFeature(GENERATE_SYNTHETIC_ANNOTATIONS));
1036: } catch (XMLConfigurationException e) {
1037: fSchemaHandler.setGenerateSyntheticAnnotations(false);
1038: }
1039: fSchemaHandler.reset(componentManager);
1040: }
1041:
1042: private boolean parserSettingsUpdated(
1043: XMLComponentManager componentManager) {
1044: try {
1045: return componentManager.getFeature(PARSER_SETTINGS);
1046: } catch (XMLConfigurationException e) {
1047: }
1048: return true;
1049: }
1050:
1051: private void initGrammarBucket() {
1052: if (fGrammarPool != null) {
1053: Grammar[] initialGrammars = fGrammarPool
1054: .retrieveInitialGrammarSet(XMLGrammarDescription.XML_SCHEMA);
1055: for (int i = 0; i < initialGrammars.length; i++) {
1056: // put this grammar into the bucket, along with grammars
1057: // imported by it (directly or indirectly)
1058: if (!fGrammarBucket.putGrammar(
1059: (SchemaGrammar) (initialGrammars[i]), true)) {
1060: // REVISIT: a conflict between new grammar(s) and grammars
1061: // in the bucket. What to do? A warning? An exception?
1062: fErrorReporter.reportError(
1063: XSMessageFormatter.SCHEMA_DOMAIN,
1064: "GrammarConflict", null,
1065: XMLErrorReporter.SEVERITY_WARNING);
1066: }
1067: }
1068: }
1069: }
1070:
1071: /* (non-Javadoc)
1072: * @see org.apache.xerces.xs.XSLoader#getConfig()
1073: */
1074: public DOMConfiguration getConfig() {
1075: return this ;
1076: }
1077:
1078: /* (non-Javadoc)
1079: * @see org.apache.xerces.xs.XSLoader#load(org.w3c.dom.ls.LSInput)
1080: */
1081: public XSModel load(LSInput is) {
1082: try {
1083: Grammar g = loadGrammar(dom2xmlInputSource(is));
1084: return ((XSGrammar) g).toXSModel();
1085: } catch (Exception e) {
1086: reportDOMFatalError(e);
1087: return null;
1088: }
1089: }
1090:
1091: /* (non-Javadoc)
1092: * @see org.apache.xerces.xs.XSLoader#loadInputList(org.apache.xerces.xs.DOMInputList)
1093: */
1094: public XSModel loadInputList(LSInputList is) {
1095: int length = is.getLength();
1096: if (length == 0) {
1097: return null;
1098: }
1099: SchemaGrammar[] gs = new SchemaGrammar[length];
1100: for (int i = 0; i < length; i++) {
1101: try {
1102: gs[i] = (SchemaGrammar) loadGrammar(dom2xmlInputSource(is
1103: .item(i)));
1104: } catch (Exception e) {
1105: reportDOMFatalError(e);
1106: return null;
1107: }
1108: }
1109: return new XSModelImpl(gs);
1110: }
1111:
1112: /* (non-Javadoc)
1113: * @see org.apache.xerces.xs.XSLoader#loadURI(java.lang.String)
1114: */
1115: public XSModel loadURI(String uri) {
1116: try {
1117: Grammar g = loadGrammar(new XMLInputSource(null, uri, null));
1118: return ((XSGrammar) g).toXSModel();
1119: } catch (Exception e) {
1120: reportDOMFatalError(e);
1121: return null;
1122: }
1123: }
1124:
1125: /* (non-Javadoc)
1126: * @see org.apache.xerces.xs.XSLoader#loadURIList(org.apache.xerces.xs.StringList)
1127: */
1128: public XSModel loadURIList(StringList uriList) {
1129: int length = uriList.getLength();
1130: if (length == 0) {
1131: return null;
1132: }
1133: SchemaGrammar[] gs = new SchemaGrammar[length];
1134: for (int i = 0; i < length; i++) {
1135: try {
1136: gs[i] = (SchemaGrammar) loadGrammar(new XMLInputSource(
1137: null, uriList.item(i), null));
1138: } catch (Exception e) {
1139: reportDOMFatalError(e);
1140: return null;
1141: }
1142: }
1143: return new XSModelImpl(gs);
1144: }
1145:
1146: void reportDOMFatalError(Exception e) {
1147: if (fErrorHandler != null) {
1148: DOMErrorImpl error = new DOMErrorImpl();
1149: error.fException = e;
1150: error.fMessage = e.getMessage();
1151: error.fSeverity = DOMError.SEVERITY_FATAL_ERROR;
1152: fErrorHandler.getErrorHandler().handleError(error);
1153: }
1154: }
1155:
1156: /* (non-Javadoc)
1157: * @see org.apache.xerces.dom3.DOMConfiguration#canSetParameter(java.lang.String, java.lang.Object)
1158: */
1159: public boolean canSetParameter(String name, Object value) {
1160: if (value instanceof Boolean) {
1161: if (name.equals(Constants.DOM_VALIDATE)
1162: || name.equals(SCHEMA_FULL_CHECKING)
1163: || name.equals(VALIDATE_ANNOTATIONS)
1164: || name.equals(CONTINUE_AFTER_FATAL_ERROR)
1165: || name.equals(ALLOW_JAVA_ENCODINGS)
1166: || name.equals(STANDARD_URI_CONFORMANT_FEATURE)
1167: || name.equals(GENERATE_SYNTHETIC_ANNOTATIONS)
1168: || name.equals(HONOUR_ALL_SCHEMALOCATIONS)) {
1169: return true;
1170:
1171: }
1172: return false;
1173: }
1174: if (name.equals(Constants.DOM_ERROR_HANDLER)
1175: || name.equals(Constants.DOM_RESOURCE_RESOLVER)
1176: || name.equals(SYMBOL_TABLE)
1177: || name.equals(ERROR_REPORTER)
1178: || name.equals(ERROR_HANDLER)
1179: || name.equals(ENTITY_RESOLVER)
1180: || name.equals(XMLGRAMMAR_POOL)
1181: || name.equals(SCHEMA_LOCATION)
1182: || name.equals(SCHEMA_NONS_LOCATION)
1183: || name.equals(JAXP_SCHEMA_SOURCE)) {
1184: return true;
1185: }
1186: return false;
1187: }
1188:
1189: /* (non-Javadoc)
1190: * @see org.apache.xerces.dom3.DOMConfiguration#getParameter(java.lang.String)
1191: */
1192: public Object getParameter(String name) throws DOMException {
1193:
1194: if (name.equals(Constants.DOM_ERROR_HANDLER)) {
1195: return (fErrorHandler != null) ? fErrorHandler
1196: .getErrorHandler() : null;
1197: } else if (name.equals(Constants.DOM_RESOURCE_RESOLVER)) {
1198: return (fResourceResolver != null) ? fResourceResolver
1199: .getEntityResolver() : null;
1200: }
1201:
1202: try {
1203: boolean feature = getFeature(name);
1204: return (feature) ? Boolean.TRUE : Boolean.FALSE;
1205: } catch (Exception e) {
1206: Object property;
1207: try {
1208: property = getProperty(name);
1209: return property;
1210: } catch (Exception ex) {
1211: String msg = DOMMessageFormatter.formatMessage(
1212: DOMMessageFormatter.DOM_DOMAIN,
1213: "FEATURE_NOT_SUPPORTED", new Object[] { name });
1214: throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1215: msg);
1216: }
1217: }
1218: }
1219:
1220: /* (non-Javadoc)
1221: * @see org.apache.xerces.dom3.DOMConfiguration#getParameterNames()
1222: */
1223: public DOMStringList getParameterNames() {
1224: if (fRecognizedParameters == null) {
1225: Vector v = new Vector();
1226: v.add(Constants.DOM_VALIDATE);
1227: v.add(Constants.DOM_ERROR_HANDLER);
1228: v.add(Constants.DOM_RESOURCE_RESOLVER);
1229: v.add(SYMBOL_TABLE);
1230: v.add(ERROR_REPORTER);
1231: v.add(ERROR_HANDLER);
1232: v.add(ENTITY_RESOLVER);
1233: v.add(XMLGRAMMAR_POOL);
1234: v.add(SCHEMA_LOCATION);
1235: v.add(SCHEMA_NONS_LOCATION);
1236: v.add(JAXP_SCHEMA_SOURCE);
1237: v.add(SCHEMA_FULL_CHECKING);
1238: v.add(CONTINUE_AFTER_FATAL_ERROR);
1239: v.add(ALLOW_JAVA_ENCODINGS);
1240: v.add(STANDARD_URI_CONFORMANT_FEATURE);
1241: v.add(VALIDATE_ANNOTATIONS);
1242: v.add(GENERATE_SYNTHETIC_ANNOTATIONS);
1243: v.add(HONOUR_ALL_SCHEMALOCATIONS);
1244: fRecognizedParameters = new DOMStringListImpl(v);
1245: }
1246: return fRecognizedParameters;
1247: }
1248:
1249: /* (non-Javadoc)
1250: * @see org.apache.xerces.dom3.DOMConfiguration#setParameter(java.lang.String, java.lang.Object)
1251: */
1252: public void setParameter(String name, Object value)
1253: throws DOMException {
1254: if (value instanceof Boolean) {
1255: boolean state = ((Boolean) value).booleanValue();
1256: if (name.equals("validate") && state) {
1257: return;
1258: }
1259: try {
1260: setFeature(name, state);
1261: } catch (Exception e) {
1262: String msg = DOMMessageFormatter.formatMessage(
1263: DOMMessageFormatter.DOM_DOMAIN,
1264: "FEATURE_NOT_SUPPORTED", new Object[] { name });
1265: throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1266: msg);
1267: }
1268: return;
1269: }
1270: if (name.equals(Constants.DOM_ERROR_HANDLER)) {
1271: if (value instanceof DOMErrorHandler) {
1272: try {
1273: fErrorHandler = new DOMErrorHandlerWrapper(
1274: (DOMErrorHandler) value);
1275: setErrorHandler(fErrorHandler);
1276: } catch (XMLConfigurationException e) {
1277: }
1278: } else {
1279: // REVISIT: type mismatch
1280: String msg = DOMMessageFormatter.formatMessage(
1281: DOMMessageFormatter.DOM_DOMAIN,
1282: "FEATURE_NOT_SUPPORTED", new Object[] { name });
1283: throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1284: msg);
1285: }
1286: return;
1287:
1288: }
1289: if (name.equals(Constants.DOM_RESOURCE_RESOLVER)) {
1290: if (value instanceof LSResourceResolver) {
1291: try {
1292: fResourceResolver = new DOMEntityResolverWrapper(
1293: (LSResourceResolver) value);
1294: setEntityResolver(fResourceResolver);
1295: } catch (XMLConfigurationException e) {
1296: }
1297: } else {
1298: // REVISIT: type mismatch
1299: String msg = DOMMessageFormatter.formatMessage(
1300: DOMMessageFormatter.DOM_DOMAIN,
1301: "FEATURE_NOT_SUPPORTED", new Object[] { name });
1302: throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
1303: msg);
1304: }
1305: return;
1306: }
1307:
1308: try {
1309: setProperty(name, value);
1310: } catch (Exception ex) {
1311:
1312: String msg = DOMMessageFormatter.formatMessage(
1313: DOMMessageFormatter.DOM_DOMAIN,
1314: "FEATURE_NOT_SUPPORTED", new Object[] { name });
1315: throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
1316:
1317: }
1318:
1319: }
1320:
1321: XMLInputSource dom2xmlInputSource(LSInput is) {
1322: // need to wrap the LSInput with an XMLInputSource
1323: XMLInputSource xis = null;
1324:
1325: /**
1326: * An LSParser looks at inputs specified in LSInput in
1327: * the following order: characterStream, byteStream,
1328: * stringData, systemId, publicId. For consistency
1329: * have the same behaviour for XSLoader.
1330: */
1331:
1332: // check whether there is a Reader
1333: // according to DOM, we need to treat such reader as "UTF-16".
1334: if (is.getCharacterStream() != null) {
1335: xis = new XMLInputSource(is.getPublicId(),
1336: is.getSystemId(), is.getBaseURI(), is
1337: .getCharacterStream(), "UTF-16");
1338: }
1339: // check whether there is an InputStream
1340: else if (is.getByteStream() != null) {
1341: xis = new XMLInputSource(is.getPublicId(),
1342: is.getSystemId(), is.getBaseURI(), is
1343: .getByteStream(), is.getEncoding());
1344: }
1345: // if there is a string data, use a StringReader
1346: // according to DOM, we need to treat such data as "UTF-16".
1347: else if (is.getStringData() != null
1348: && is.getStringData().length() != 0) {
1349: xis = new XMLInputSource(is.getPublicId(),
1350: is.getSystemId(), is.getBaseURI(),
1351: new StringReader(is.getStringData()), "UTF-16");
1352: }
1353: // otherwise, just use the public/system/base Ids
1354: else {
1355: xis = new XMLInputSource(is.getPublicId(),
1356: is.getSystemId(), is.getBaseURI());
1357: }
1358:
1359: return xis;
1360: }
1361:
1362: } // XMLGrammarLoader
|