/*
* Copyright (c) 2012-2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
/*
* Copyright 2000-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.org.apache.xerces.internal.impl.xs;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.util.Hashtable;
import java.util.Locale;
import java.util.StringTokenizer;
import java.util.Vector;
import com.sun.org.apache.xerces.internal.dom.DOMErrorImpl;
import com.sun.org.apache.xerces.internal.dom.DOMMessageFormatter;
import com.sun.org.apache.xerces.internal.dom.DOMStringListImpl;
import com.sun.org.apache.xerces.internal.impl.Constants;
import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
import com.sun.org.apache.xerces.internal.impl.dv.DVFactoryException;
import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeValueException;
import com.sun.org.apache.xerces.internal.impl.dv.SchemaDVFactory;
import com.sun.org.apache.xerces.internal.impl.dv.xs.SchemaDVFactoryImpl;
import com.sun.org.apache.xerces.internal.impl.xs.models.CMBuilder;
import com.sun.org.apache.xerces.internal.impl.xs.models.CMNodeFactory;
import com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler;
import com.sun.org.apache.xerces.internal.util.DOMEntityResolverWrapper;
import com.sun.org.apache.xerces.internal.util.DOMErrorHandlerWrapper;
import com.sun.org.apache.xerces.internal.util.DefaultErrorHandler;
import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings;
import com.sun.org.apache.xerces.internal.util.Status;
import com.sun.org.apache.xerces.internal.util.SymbolTable;
import com.sun.org.apache.xerces.internal.util.XMLSymbols;
import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
import com.sun.org.apache.xerces.internal.xni.XNIException;
import com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarLoader;
import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
import com.sun.org.apache.xerces.internal.xni.grammars.XSGrammar;
import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent;
import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
import com.sun.org.apache.xerces.internal.xs.LSInputList;
import com.sun.org.apache.xerces.internal.xs.StringList;
import com.sun.org.apache.xerces.internal.xs.XSLoader;
import com.sun.org.apache.xerces.internal.xs.XSModel;
import java.util.HashMap;
import java.util.Map;
import javax.xml.XMLConstants;
import org.w3c.dom.DOMConfiguration;
import org.w3c.dom.DOMError;
import org.w3c.dom.DOMErrorHandler;
import org.w3c.dom.DOMStringList;
import org.w3c.dom.DOMException;
import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSResourceResolver;
import org.xml.sax.InputSource;
/**
* This class implements xni.grammars.XMLGrammarLoader.
* It also serves as implementation of xs.XSLoader interface and DOMConfiguration interface.
*
* This class is designed to interact either with a proxy for a user application
* which wants to preparse schemas, or with our own Schema validator.
* It is hoped that none of these "external" classes will therefore need to communicate directly
* with XSDHandler in future.
* <p>This class only knows how to make XSDHandler do its thing.
* The caller must ensure that all its properties (schemaLocation, JAXPSchemaSource
* etc.) have been properly set.
*
* @xerces.internal
*
* @author Neil Graham, IBM
* @version $Id: XMLSchemaLoader.java,v 1.10 2010-11-01 04:39:55 joehw Exp $
*/
public class XMLSchemaLoader implements XMLGrammarLoader, XMLComponent,
// XML Component API
XSLoader, DOMConfiguration {
// Feature identifiers:
/** Feature identifier: schema full checking*/
protected static final String SCHEMA_FULL_CHECKING =
Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_FULL_CHECKING;
/** Feature identifier: continue after fatal error. */
protected static final String CONTINUE_AFTER_FATAL_ERROR =
Constants.XERCES_FEATURE_PREFIX + Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE;
/** Feature identifier: allow java encodings to be recognized when parsing schema docs. */
protected static final String ALLOW_JAVA_ENCODINGS =
Constants.XERCES_FEATURE_PREFIX + Constants.ALLOW_JAVA_ENCODINGS_FEATURE;
/** Feature identifier: standard uri conformant feature. */
protected static final String STANDARD_URI_CONFORMANT_FEATURE =
Constants.XERCES_FEATURE_PREFIX + Constants.STANDARD_URI_CONFORMANT_FEATURE;
/** Feature identifier: validate annotations. */
protected static final String VALIDATE_ANNOTATIONS =
Constants.XERCES_FEATURE_PREFIX + Constants.VALIDATE_ANNOTATIONS_FEATURE;
/** Feature: disallow doctype*/
protected static final String DISALLOW_DOCTYPE =
Constants.XERCES_FEATURE_PREFIX + Constants.DISALLOW_DOCTYPE_DECL_FEATURE;
/** Feature: generate synthetic annotations */
protected static final String GENERATE_SYNTHETIC_ANNOTATIONS =
Constants.XERCES_FEATURE_PREFIX + Constants.GENERATE_SYNTHETIC_ANNOTATIONS_FEATURE;
/** Feature identifier: honour all schemaLocations */
protected static final String HONOUR_ALL_SCHEMALOCATIONS =
Constants.XERCES_FEATURE_PREFIX + Constants.HONOUR_ALL_SCHEMALOCATIONS_FEATURE;
protected static final String AUGMENT_PSVI =
Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_AUGMENT_PSVI;
protected static final String PARSER_SETTINGS =
Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS;
/** Feature identifier: namespace growth */
protected static final String NAMESPACE_GROWTH =
Constants.XERCES_FEATURE_PREFIX + Constants.NAMESPACE_GROWTH_FEATURE;
/** Feature identifier: tolerate duplicates */
protected static final String TOLERATE_DUPLICATES =
Constants.XERCES_FEATURE_PREFIX + Constants.TOLERATE_DUPLICATES_FEATURE;
/** Property identifier: Schema DV Factory */
protected static final String SCHEMA_DV_FACTORY =
Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_DV_FACTORY_PROPERTY;
protected static final String USE_SERVICE_MECHANISM = Constants.ORACLE_FEATURE_SERVICE_MECHANISM;
// recognized features:
private static final String[] RECOGNIZED_FEATURES = {
SCHEMA_FULL_CHECKING,
AUGMENT_PSVI,
CONTINUE_AFTER_FATAL_ERROR,
ALLOW_JAVA_ENCODINGS,
STANDARD_URI_CONFORMANT_FEATURE,
DISALLOW_DOCTYPE,
GENERATE_SYNTHETIC_ANNOTATIONS,
VALIDATE_ANNOTATIONS,
HONOUR_ALL_SCHEMALOCATIONS,
NAMESPACE_GROWTH,
TOLERATE_DUPLICATES,
USE_SERVICE_MECHANISM
};
// property identifiers
/** Property identifier: symbol table. */
public static final String SYMBOL_TABLE =
Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
/** Property identifier: error reporter. */
public static final String ERROR_REPORTER =
Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
/** Property identifier: error handler. */
protected static final String ERROR_HANDLER =
Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_HANDLER_PROPERTY;
/** Property identifier: entity resolver. */
public static final String ENTITY_RESOLVER =
Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY;
/** Property identifier: grammar pool. */
public static final String XMLGRAMMAR_POOL =
Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY;
/** Property identifier: schema location. */
protected static final String SCHEMA_LOCATION =
Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_LOCATION;
/** Property identifier: no namespace schema location. */
protected static final String SCHEMA_NONS_LOCATION =
Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_NONS_LOCATION;
/** Property identifier: JAXP schema source. */
protected static final String JAXP_SCHEMA_SOURCE =
Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE;
protected static final String SECURITY_MANAGER =
Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
/** Property identifier: locale. */
protected static final String LOCALE =
Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY;
protected static final String ENTITY_MANAGER =
Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY;
/** Property identifier: Security property manager. */
private static final String XML_SECURITY_PROPERTY_MANAGER =
Constants.XML_SECURITY_PROPERTY_MANAGER;
/** Property identifier: access to external dtd */
public static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD;
/** Property identifier: access to external schema */
public static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA;
// recognized properties
private static final String [] RECOGNIZED_PROPERTIES = {
ENTITY_MANAGER,
SYMBOL_TABLE,
ERROR_REPORTER,
ERROR_HANDLER,
ENTITY_RESOLVER,
XMLGRAMMAR_POOL,
SCHEMA_LOCATION,
SCHEMA_NONS_LOCATION,
JAXP_SCHEMA_SOURCE,
SECURITY_MANAGER,
LOCALE,
SCHEMA_DV_FACTORY,
XML_SECURITY_PROPERTY_MANAGER
};
// Data
// features and properties
private ParserConfigurationSettings fLoaderConfig = new ParserConfigurationSettings();
private SymbolTable fSymbolTable = null;
private XMLErrorReporter fErrorReporter = new XMLErrorReporter ();
private XMLEntityManager fEntityManager = null;
private XMLEntityResolver fUserEntityResolver = null;
private XMLGrammarPool fGrammarPool = null;
private String fExternalSchemas = null;
private String fExternalNoNSSchema = null;
// JAXP property: schema source
private Object fJAXPSource = null;
// is Schema Full Checking enabled
private boolean fIsCheckedFully = false;
// boolean that tells whether we've tested the JAXP property.
private boolean fJAXPProcessed = false;
// if features/properties has not been changed, the value of this attribute is "false"
private boolean fSettingsChanged = true;
// xml schema parsing
private XSDHandler fSchemaHandler;
private XSGrammarBucket fGrammarBucket;
private XSDeclarationPool fDeclPool = null;
private SubstitutionGroupHandler fSubGroupHandler;
private final CMNodeFactory fNodeFactory = new CMNodeFactory(); //component mgr will be set later
private CMBuilder fCMBuilder;
private XSDDescription fXSDDescription = new XSDDescription();
private String faccessExternalSchema = Constants.EXTERNAL_ACCESS_DEFAULT;
private Map fJAXPCache;
private Locale fLocale = Locale.getDefault();
// XSLoader attributes
private DOMStringList fRecognizedParameters = null;
/** DOM L3 error handler */
private DOMErrorHandlerWrapper fErrorHandler = null;
/** DOM L3 resource resolver */
private DOMEntityResolverWrapper fResourceResolver = null;
// default constructor. Create objects we absolutely need:
public XMLSchemaLoader() {
this( new SymbolTable(), null, new XMLEntityManager(), null, null, null);
}
public XMLSchemaLoader(SymbolTable symbolTable) {
this( symbolTable, null, new XMLEntityManager(), null, null, null);
}
/**
* This constractor is used by the XMLSchemaValidator. Additional properties, i.e. XMLEntityManager,
* will be passed during reset(XMLComponentManager).
* @param errorReporter
* @param grammarBucket
* @param sHandler
* @param builder
*/
XMLSchemaLoader(XMLErrorReporter errorReporter,
XSGrammarBucket grammarBucket,
SubstitutionGroupHandler sHandler, CMBuilder builder) {
this(null, errorReporter, null, grammarBucket, sHandler, builder);
}
XMLSchemaLoader(SymbolTable symbolTable,
XMLErrorReporter errorReporter,
XMLEntityManager entityResolver,
XSGrammarBucket grammarBucket,
SubstitutionGroupHandler sHandler,
CMBuilder builder) {
// store properties and features in configuration
fLoaderConfig.addRecognizedFeatures(RECOGNIZED_FEATURES);
fLoaderConfig.addRecognizedProperties(RECOGNIZED_PROPERTIES);
if (symbolTable != null){
fLoaderConfig.setProperty(SYMBOL_TABLE, symbolTable);
}
if(errorReporter == null) {
errorReporter = new XMLErrorReporter ();
errorReporter.setLocale(fLocale);
errorReporter.setProperty(ERROR_HANDLER, new DefaultErrorHandler());
}
fErrorReporter = errorReporter;
// make sure error reporter knows about schemas...
if(fErrorReporter.getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN) == null) {
fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, new XSMessageFormatter());
}
fLoaderConfig.setProperty(ERROR_REPORTER, fErrorReporter);
fEntityManager = entityResolver;
// entity manager is null if XMLSchemaValidator creates the loader
if (fEntityManager != null){
fLoaderConfig.setProperty(ENTITY_MANAGER, fEntityManager);
}
// by default augment PSVI (i.e. don't use declaration pool)
fLoaderConfig.setFeature(AUGMENT_PSVI, true);
if(grammarBucket == null ) {
grammarBucket = new XSGrammarBucket();
}
fGrammarBucket = grammarBucket;
if(sHandler == null) {
sHandler = new SubstitutionGroupHandler(fGrammarBucket);
}
fSubGroupHandler = sHandler;
if(builder == null) {
builder = new CMBuilder(fNodeFactory);
}
fCMBuilder = builder;
fSchemaHandler = new XSDHandler(fGrammarBucket);
if (fDeclPool != null) {
fDeclPool.reset();
}
fJAXPCache = new HashMap();
fSettingsChanged = true;
}
/**
* Returns a list of feature identifiers that are recognized by
* this XMLGrammarLoader. This method may return null if no features
* are recognized.
*/
public String[] getRecognizedFeatures() {
return (String[])(RECOGNIZED_FEATURES.clone());
} // getRecognizedFeatures(): String[]
/**
* Returns the state of a feature.
*
* @param featureId The feature identifier.
*
* @throws XMLConfigurationException Thrown on configuration error.
*/
public boolean getFeature(String featureId)
throws XMLConfigurationException {
return fLoaderConfig.getFeature(featureId);
} // getFeature (String): boolean
/**
* Sets the state of a feature.
*
* @param featureId The feature identifier.
* @param state The state of the feature.
*
* @throws XMLConfigurationException Thrown when a feature is not
* recognized or cannot be set.
*/
public void setFeature(String featureId,
boolean state) throws XMLConfigurationException {
fSettingsChanged = true;
if(featureId.equals(CONTINUE_AFTER_FATAL_ERROR)) {
fErrorReporter.setFeature(CONTINUE_AFTER_FATAL_ERROR, state);
}
else if(featureId.equals(GENERATE_SYNTHETIC_ANNOTATIONS)) {
fSchemaHandler.setGenerateSyntheticAnnotations(state);
}
fLoaderConfig.setFeature(featureId, state);
} // setFeature(String, boolean)
/**
* Returns a list of property identifiers that are recognized by
* this XMLGrammarLoader. This method may return null if no properties
* are recognized.
*/
public String[] getRecognizedProperties() {
return (String[])(RECOGNIZED_PROPERTIES.clone());
} // getRecognizedProperties(): String[]
/**
* Returns the state of a property.
*
* @param propertyId The property identifier.
*
* @throws XMLConfigurationException Thrown on configuration error.
*/
public Object getProperty(String propertyId)
throws XMLConfigurationException {
return fLoaderConfig.getProperty(propertyId);
} // getProperty(String): Object
/**
* Sets the state of a property.
*
* @param propertyId The property identifier.
* @param state The state of the property.
*
* @throws XMLConfigurationException Thrown when a property is not
* recognized or cannot be set.
*/
public void setProperty(String propertyId,
Object state) throws XMLConfigurationException {
fSettingsChanged = true;
fLoaderConfig.setProperty(propertyId, state);
if (propertyId.equals(JAXP_SCHEMA_SOURCE)) {
fJAXPSource = state;
fJAXPProcessed = false;
}
else if (propertyId.equals(XMLGRAMMAR_POOL)) {
fGrammarPool = (XMLGrammarPool)state;
}
else if (propertyId.equals(SCHEMA_LOCATION)) {
fExternalSchemas = (String)state;
}
else if (propertyId.equals(SCHEMA_NONS_LOCATION)) {
fExternalNoNSSchema = (String) state;
}
else if (propertyId.equals(LOCALE)) {
setLocale((Locale) state);
}
else if (propertyId.equals(ENTITY_RESOLVER)) {
fEntityManager.setProperty(ENTITY_RESOLVER, state);
}
else if (propertyId.equals(ERROR_REPORTER)) {
fErrorReporter = (XMLErrorReporter)state;
if (fErrorReporter.getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN) == null) {
fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, new XSMessageFormatter());
}
}
else if (propertyId.equals(XML_SECURITY_PROPERTY_MANAGER)) {
XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager)state;
faccessExternalSchema = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA);
}
} // setProperty(String, Object)
/**
* Set the locale to use for messages.
*
* @param locale The locale object to use for localization of messages.
*
* @exception XNIException Thrown if the parser does not support the
* specified locale.
*/
public void setLocale(Locale locale) {
fLocale = locale;
fErrorReporter.setLocale(locale);
} // setLocale(Locale)
/** Return the Locale the XMLGrammarLoader is using. */
public Locale getLocale() {
return fLocale;
} // getLocale(): Locale
/**
* Sets the error handler.
*
* @param errorHandler The error handler.
*/
public void setErrorHandler(XMLErrorHandler errorHandler) {
fErrorReporter.setProperty(ERROR_HANDLER, errorHandler);
} // setErrorHandler(XMLErrorHandler)
/** Returns the registered error handler. */
public XMLErrorHandler getErrorHandler() {
return fErrorReporter.getErrorHandler();
} // getErrorHandler(): XMLErrorHandler
/**
* Sets the entity resolver.
*
* @param entityResolver The new entity resolver.
*/
public void setEntityResolver(XMLEntityResolver entityResolver) {
fUserEntityResolver = entityResolver;
fLoaderConfig.setProperty(ENTITY_RESOLVER, entityResolver);
fEntityManager.setProperty(ENTITY_RESOLVER, entityResolver);
} // setEntityResolver(XMLEntityResolver)
/** Returns the registered entity resolver. */
public XMLEntityResolver getEntityResolver() {
return fUserEntityResolver;
} // getEntityResolver(): XMLEntityResolver
/**
* Returns a Grammar object by parsing the contents of the
* entities pointed to by sources.
*
* @param source[] the locations of the entity which forms
* the staring point of the grammars to be constructed
* @throws IOException when a problem is encounted reading the entity
* @throws XNIException when a condition arises (such as a FatalError) that requires parsing
* of the entity be terminated
*/
public void loadGrammar(XMLInputSource source[])
throws IOException, XNIException {
int numSource = source.length;
for (int i = 0; i < numSource; ++i) {
loadGrammar(source[i]);
}
}
/**
* Returns a Grammar object by parsing the contents of the
* entity pointed to by source.
*
* @param source the location of the entity which forms
* the starting point of the grammar to be constructed.
* @throws IOException When a problem is encountered reading the entity
* XNIException When a condition arises (such as a FatalError) that requires parsing
* of the entity be terminated.
*/
public Grammar loadGrammar(XMLInputSource source)
throws IOException, XNIException {
// REVISIT: this method should have a namespace parameter specified by
// user. In this case we can easily detect if a schema asked to be loaded
// is already in the local cache.
reset(fLoaderConfig);
fSettingsChanged = false;
XSDDescription desc = new XSDDescription();
desc.fContextType = XSDDescription.CONTEXT_PREPARSE;
desc.setBaseSystemId(source.getBaseSystemId());
desc.setLiteralSystemId( source.getSystemId());
// none of the other fields make sense for preparsing
Map locationPairs = new HashMap();
// Process external schema location properties.
// We don't call tokenizeSchemaLocationStr here, because we also want
// to check whether the values are valid URI.
processExternalHints(fExternalSchemas, fExternalNoNSSchema,
locationPairs, fErrorReporter);
SchemaGrammar grammar = loadSchema(desc, source, locationPairs);
if(grammar != null && fGrammarPool != null) {
fGrammarPool.cacheGrammars(XMLGrammarDescription.XML_SCHEMA, fGrammarBucket.getGrammars());
// NOTE: we only need to verify full checking in case the schema was not provided via JAXP
// since full checking already verified for all JAXP schemas
if(fIsCheckedFully && fJAXPCache.get(grammar) != grammar) {
XSConstraints.fullSchemaChecking(fGrammarBucket, fSubGroupHandler, fCMBuilder, fErrorReporter);
}
}
return grammar;
} // loadGrammar(XMLInputSource): Grammar
/**
* This method is called either from XMLGrammarLoader.loadGrammar or from XMLSchemaValidator.
* Note: in either case, the EntityManager (or EntityResolvers) are not going to be invoked
* to resolve the location of the schema in XSDDescription
* @param desc
* @param source
* @param locationPairs
* @return An XML Schema grammar
* @throws IOException
* @throws XNIException
*/
SchemaGrammar loadSchema(XSDDescription desc,
XMLInputSource source,
Map locationPairs) throws IOException, XNIException {
// this should only be done once per invocation of this object;
// unless application alters JAXPSource in the mean time.
if(!fJAXPProcessed) {
processJAXPSchemaSource(locationPairs);
}
if (desc.isExternal()) {
String accessError = SecuritySupport.checkAccess(desc.getExpandedSystemId(), faccessExternalSchema, Constants.ACCESS_EXTERNAL_ALL);
if (accessError != null) {
throw new XNIException(fErrorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
"schema_reference.access",
new Object[] { SecuritySupport.sanitizePath(desc.getExpandedSystemId()), accessError }, XMLErrorReporter.SEVERITY_ERROR));
}
}
SchemaGrammar grammar = fSchemaHandler.parseSchema(source, desc, locationPairs);
return grammar;
} // loadSchema(XSDDescription, XMLInputSource): SchemaGrammar
/** This method tries to resolve location of the given schema.
* The loader stores the namespace/location pairs in a hashtable (use "" as the
* namespace of absent namespace). When resolving an entity, loader first tries
* to find in the hashtable whether there is a value for that namespace,
* if so, pass that location value to the user-defined entity resolver.
*
* @param desc
* @param locationPairs
* @param entityResolver
* @return
* @throws IOException
*/
public static XMLInputSource resolveDocument(XSDDescription desc, Map locationPairs,
XMLEntityResolver entityResolver) throws IOException {
String loc = null;
// we consider the schema location properties for import
if (desc.getContextType() == XSDDescription.CONTEXT_IMPORT ||
desc.fromInstance()) {
// use empty string as the key for absent namespace
String namespace = desc.getTargetNamespace();
String ns = namespace == null ? XMLSymbols.EMPTY_STRING : namespace;
// get the location hint for that namespace
LocationArray tempLA = (LocationArray)locationPairs.get(ns);
if(tempLA != null)
loc = tempLA.getFirstLocation();
}
// if it's not import, or if the target namespace is not set
// in the schema location properties, use location hint
if (loc == null) {
String[] hints = desc.getLocationHints();
if (hints != null && hints.length > 0)
loc = hints[0];
}
String expandedLoc = XMLEntityManager.expandSystemId(loc, desc.getBaseSystemId(), false);
desc.setLiteralSystemId(loc);
desc.setExpandedSystemId(expandedLoc);
return entityResolver.resolveEntity(desc);
}
// add external schema locations to the location pairs
public static void processExternalHints(String sl, String nsl,
Map locations,
XMLErrorReporter er) {
if (sl != null) {
try {
// get the attribute decl for xsi:schemaLocation
// because external schema location property has the same syntax
// as xsi:schemaLocation
XSAttributeDecl attrDecl = SchemaGrammar.SG_XSI.getGlobalAttributeDecl(SchemaSymbols.XSI_SCHEMALOCATION);
// validation the string value to get the list of URI's
attrDecl.fType.validate(sl, null, null);
if (!tokenizeSchemaLocationStr(sl, locations)) {
// report warning (odd number of items)
er.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
"SchemaLocation",
new Object[]{sl},
XMLErrorReporter.SEVERITY_WARNING);
}
}
catch (InvalidDatatypeValueException ex) {
// report warning (not list of URI's)
er.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
ex.getKey(), ex.getArgs(),
XMLErrorReporter.SEVERITY_WARNING);
}
}
if (nsl != null) {
try {
// similarly for no ns schema location property
XSAttributeDecl attrDecl = SchemaGrammar.SG_XSI.getGlobalAttributeDecl(SchemaSymbols.XSI_NONAMESPACESCHEMALOCATION);
attrDecl.fType.validate(nsl, null, null);
LocationArray la = ((LocationArray)locations.get(XMLSymbols.EMPTY_STRING));
if(la == null) {
la = new LocationArray();
locations.put(XMLSymbols.EMPTY_STRING, la);
}
la.addLocation(nsl);
}
catch (InvalidDatatypeValueException ex) {
// report warning (not a URI)
er.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
ex.getKey(), ex.getArgs(),
XMLErrorReporter.SEVERITY_WARNING);
}
}
}
// this method takes a SchemaLocation string.
// If an error is encountered, false is returned;
// otherwise, true is returned. In either case, locations
// is augmented to include as many tokens as possible.
// @param schemaStr The schemaLocation string to tokenize
// @param locations HashMap mapping namespaces to LocationArray objects holding lists of locaitons
// @return true if no problems; false if string could not be tokenized
public static boolean tokenizeSchemaLocationStr(String schemaStr, Map locations) {
if (schemaStr!= null) {
StringTokenizer t = new StringTokenizer(schemaStr, " \n\t\r");
String namespace, location;
while (t.hasMoreTokens()) {
namespace = t.nextToken ();
if (!t.hasMoreTokens()) {
return false; // error!
}
location = t.nextToken();
LocationArray la = ((LocationArray)locations.get(namespace));
if(la == null) {
la = new LocationArray();
locations.put(namespace, la);
}
la.addLocation(location);
}
}
return true;
} // tokenizeSchemaLocation(String, HashMap): boolean
/**
* Translate the various JAXP SchemaSource property types to XNI
* XMLInputSource. Valid types are: String, org.xml.sax.InputSource,
* InputStream, File, or Object[] of any of previous types.
* REVISIT: the JAXP 1.2 spec is less than clear as to whether this property
* should be available to imported schemas. I have assumed
* that it should. - NG
* Note: all JAXP schema files will be checked for full-schema validity if the feature was set up
*
*/
private void processJAXPSchemaSource(Map locationPairs) throws IOException {
fJAXPProcessed = true;
if (fJAXPSource == null) {
return;
}
Class componentType = fJAXPSource.getClass().getComponentType();
XMLInputSource xis = null;
String sid = null;
if (componentType == null) {
// Not an array
if(fJAXPSource instanceof InputStream ||
fJAXPSource instanceof InputSource) {
SchemaGrammar g = (SchemaGrammar)fJAXPCache.get(fJAXPSource);
if(g != null) {
fGrammarBucket.putGrammar(g);
return;
}
}
fXSDDescription.reset();
xis = xsdToXMLInputSource(fJAXPSource);
sid = xis.getSystemId();
fXSDDescription.fContextType = XSDDescription.CONTEXT_PREPARSE;
if (sid != null) {
fXSDDescription.setBaseSystemId(xis.getBaseSystemId());
fXSDDescription.setLiteralSystemId(sid);
fXSDDescription.setExpandedSystemId(sid);
fXSDDescription.fLocationHints = new String[]{sid};
}
SchemaGrammar g = loadSchema(fXSDDescription, xis, locationPairs);
// it is possible that we won't be able to resolve JAXP schema-source location
if (g != null){
if(fJAXPSource instanceof InputStream ||
fJAXPSource instanceof InputSource) {
fJAXPCache.put(fJAXPSource, g);
if(fIsCheckedFully) {
XSConstraints.fullSchemaChecking(fGrammarBucket, fSubGroupHandler, fCMBuilder, fErrorReporter);
}
}
fGrammarBucket.putGrammar(g);
}
return ;
} else if ( (componentType != Object.class) &&
(componentType != String.class) &&
(componentType != File.class) &&
(componentType != InputStream.class) &&
(componentType != InputSource.class)
) {
// Not an Object[], String[], File[], InputStream[], InputSource[]
throw new XMLConfigurationException(
Status.NOT_SUPPORTED, "\""+JAXP_SCHEMA_SOURCE+
"\" property cannot have an array of type {"+componentType.getName()+
"}. Possible types of the array supported are Object, String, File, "+
"InputStream, InputSource.");
}
// JAXP spec. allow []s of type String, File, InputStream,
// InputSource also, apart from [] of type Object.
Object[] objArr = (Object[]) fJAXPSource;
//make local vector for storing targetn namespaces of schemasources specified in object arrays.
Vector jaxpSchemaSourceNamespaces = new Vector() ;
for (int i = 0; i < objArr.length; i++) {
if(objArr[i] instanceof InputStream ||
objArr[i] instanceof InputSource) {
SchemaGrammar g = (SchemaGrammar)fJAXPCache.get(objArr[i]);
if (g != null) {
fGrammarBucket.putGrammar(g);
continue;
}
}
fXSDDescription.reset();
xis = xsdToXMLInputSource(objArr[i]);
sid = xis.getSystemId();
fXSDDescription.fContextType = XSDDescription.CONTEXT_PREPARSE;
if (sid != null) {
fXSDDescription.setBaseSystemId(xis.getBaseSystemId());
fXSDDescription.setLiteralSystemId(sid);
fXSDDescription.setExpandedSystemId(sid);
fXSDDescription.fLocationHints = new String[]{sid};
}
String targetNamespace = null ;
// load schema
SchemaGrammar grammar = fSchemaHandler.parseSchema(xis,fXSDDescription, locationPairs);
if(fIsCheckedFully) {
XSConstraints.fullSchemaChecking(fGrammarBucket, fSubGroupHandler, fCMBuilder, fErrorReporter);
}
if(grammar != null){
targetNamespace = grammar.getTargetNamespace() ;
if(jaxpSchemaSourceNamespaces.contains(targetNamespace)){
//when an array of objects is passed it is illegal to have two schemas that share same namespace.
throw new java.lang.IllegalArgumentException(
" When using array of Objects as the value of SCHEMA_SOURCE property , " +
"no two Schemas should share the same targetNamespace. " );
}
else{
jaxpSchemaSourceNamespaces.add(targetNamespace) ;
}
if(objArr[i] instanceof InputStream ||
objArr[i] instanceof InputSource) {
fJAXPCache.put(objArr[i], grammar);
}
fGrammarBucket.putGrammar(grammar);
}
else{
//REVISIT: What should be the acutal behavior if grammar can't be loaded as specified in schema source?
}
}
}//processJAXPSchemaSource
private XMLInputSource xsdToXMLInputSource(
Object val)
{
if (val instanceof String) {
// String value is treated as a URI that is passed through the
// EntityResolver
String loc = (String) val;
fXSDDescription.reset();
fXSDDescription.setValues(null, loc, null, null);
XMLInputSource xis = null;
try {
xis = fEntityManager.resolveEntity(fXSDDescription);
} catch (IOException ex) {
fErrorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
"schema_reference.4",
new Object[] { loc }, XMLErrorReporter.SEVERITY_ERROR);
}
if (xis == null) {
// REVISIT: can this happen?
// Treat value as a URI and pass in as systemId
return new XMLInputSource(null, loc, null);
}
return xis;
} else if (val instanceof InputSource) {
return saxToXMLInputSource((InputSource) val);
} else if (val instanceof InputStream) {
return new XMLInputSource(null, null, null,
(InputStream) val, null);
} else if (val instanceof File) {
File file = (File) val;
InputStream is = null;
try {
is = new BufferedInputStream(new FileInputStream(file));
} catch (FileNotFoundException ex) {
fErrorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
"schema_reference.4", new Object[] { file.toString() },
XMLErrorReporter.SEVERITY_ERROR);
}
return new XMLInputSource(null, null, null, is, null);
}
throw new XMLConfigurationException(
Status.NOT_SUPPORTED, "\""+JAXP_SCHEMA_SOURCE+
"\" property cannot have a value of type {"+val.getClass().getName()+
"}. Possible types of the value supported are String, File, InputStream, "+
"InputSource OR an array of these types.");
}
//Convert a SAX InputSource to an equivalent XNI XMLInputSource
private static XMLInputSource saxToXMLInputSource(InputSource sis) {
String publicId = sis.getPublicId();
String systemId = sis.getSystemId();
Reader charStream = sis.getCharacterStream();
if (charStream != null) {
return new XMLInputSource(publicId, systemId, null, charStream,
null);
}
InputStream byteStream = sis.getByteStream();
if (byteStream != null) {
return new XMLInputSource(publicId, systemId, null, byteStream,
sis.getEncoding());
}
return new XMLInputSource(publicId, systemId, null);
}
static class LocationArray{
int length ;
String [] locations = new String[2];
public void resize(int oldLength , int newLength){
String [] temp = new String[newLength] ;
System.arraycopy(locations, 0, temp, 0, Math.min(oldLength, newLength));
locations = temp ;
length = Math.min(oldLength, newLength);
}
public void addLocation(String location){
if(length >= locations.length ){
resize(length, Math.max(1, length*2));
}
locations[length++] = location;
}//setLocation()
public String [] getLocationArray(){
if(length < locations.length ){
resize(locations.length, length);
}
return locations;
}//getLocationArray()
public String getFirstLocation(){
return length > 0 ? locations[0] : null;
}
public int getLength(){
return length ;
}
} //locationArray
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xni.parser.XMLComponent#getFeatureDefault(java.lang.String)
*/
public Boolean getFeatureDefault(String featureId) {
if (featureId.equals(AUGMENT_PSVI)){
return Boolean.TRUE;
}
return null;
}
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xni.parser.XMLComponent#getPropertyDefault(java.lang.String)
*/
public Object getPropertyDefault(String propertyId) {
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xni.parser.XMLComponent#reset(com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager)
*/
public void reset(XMLComponentManager componentManager) throws XMLConfigurationException {
fGrammarBucket.reset();
fSubGroupHandler.reset();
boolean parser_settings = componentManager.getFeature(PARSER_SETTINGS, true);
if (!parser_settings || !fSettingsChanged){
// need to reprocess JAXP schema sources
fJAXPProcessed = false;
// reinitialize grammar bucket
initGrammarBucket();
return;
}
//pass the component manager to the factory..
fNodeFactory.reset(componentManager);
// get registered entity manager to be able to resolve JAXP schema-source property:
// Note: in case XMLSchemaValidator has created the loader,
// the entity manager property is null
fEntityManager = (XMLEntityManager)componentManager.getProperty(ENTITY_MANAGER);
// get the error reporter
fErrorReporter = (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER);
// Determine schema dv factory to use
SchemaDVFactory dvFactory = null;
dvFactory = fSchemaHandler.getDVFactory();
if (dvFactory == null) {
dvFactory = SchemaDVFactory.getInstance();
fSchemaHandler.setDVFactory(dvFactory);
}
boolean psvi = componentManager.getFeature(AUGMENT_PSVI, false);
if (!psvi) {
if (fDeclPool != null) {
fDeclPool.reset();
}
else {
fDeclPool = new XSDeclarationPool();
}
fCMBuilder.setDeclPool(fDeclPool);
fSchemaHandler.setDeclPool(fDeclPool);
if (dvFactory instanceof SchemaDVFactoryImpl) {
fDeclPool.setDVFactory((SchemaDVFactoryImpl)dvFactory);
((SchemaDVFactoryImpl)dvFactory).setDeclPool(fDeclPool);
}
} else {
fCMBuilder.setDeclPool(null);
fSchemaHandler.setDeclPool(null);
}
// get schema location properties
try {
fExternalSchemas = (String) componentManager.getProperty(SCHEMA_LOCATION);
fExternalNoNSSchema = (String) componentManager.getProperty(SCHEMA_NONS_LOCATION);
} catch (XMLConfigurationException e) {
fExternalSchemas = null;
fExternalNoNSSchema = null;
}
// get JAXP sources if available
fJAXPSource = componentManager.getProperty(JAXP_SCHEMA_SOURCE, null);
fJAXPProcessed = false;
// clear grammars, and put the one for schema namespace there
fGrammarPool = (XMLGrammarPool) componentManager.getProperty(XMLGRAMMAR_POOL, null);
initGrammarBucket();
// get continue-after-fatal-error feature
try {
boolean fatalError = componentManager.getFeature(CONTINUE_AFTER_FATAL_ERROR, false);
if (!fatalError) {
fErrorReporter.setFeature(CONTINUE_AFTER_FATAL_ERROR, fatalError);
}
} catch (XMLConfigurationException e) {
}
// set full validation to false
fIsCheckedFully = componentManager.getFeature(SCHEMA_FULL_CHECKING, false);
// get generate-synthetic-annotations feature
fSchemaHandler.setGenerateSyntheticAnnotations(componentManager.getFeature(GENERATE_SYNTHETIC_ANNOTATIONS, false));
fSchemaHandler.reset(componentManager);
XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager)componentManager.getProperty(XML_SECURITY_PROPERTY_MANAGER);
faccessExternalSchema = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA);
}
private void initGrammarBucket(){
if(fGrammarPool != null) {
Grammar [] initialGrammars = fGrammarPool.retrieveInitialGrammarSet(XMLGrammarDescription.XML_SCHEMA);
for (int i = 0; i < initialGrammars.length; i++) {
// put this grammar into the bucket, along with grammars
// imported by it (directly or indirectly)
if (!fGrammarBucket.putGrammar((SchemaGrammar)(initialGrammars[i]), true)) {
// REVISIT: a conflict between new grammar(s) and grammars
// in the bucket. What to do? A warning? An exception?
fErrorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
"GrammarConflict", null,
XMLErrorReporter.SEVERITY_WARNING);
}
}
}
}
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xs.XSLoader#getConfig()
*/
public DOMConfiguration getConfig() {
return this;
}
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xs.XSLoader#load(org.w3c.dom.ls.LSInput)
*/
public XSModel load(LSInput is) {
try {
Grammar g = loadGrammar(dom2xmlInputSource(is));
return ((XSGrammar) g).toXSModel();
} catch (Exception e) {
reportDOMFatalError(e);
return null;
}
}
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xs.XSLoader#loadInputList(com.sun.org.apache.xerces.internal.xs.DOMInputList)
*/
public XSModel loadInputList(LSInputList is) {
int length = is.getLength();
SchemaGrammar[] gs = new SchemaGrammar[length];
for (int i = 0; i < length; i++) {
try {
gs[i] = (SchemaGrammar) loadGrammar(dom2xmlInputSource(is.item(i)));
} catch (Exception e) {
reportDOMFatalError(e);
return null;
}
}
return new XSModelImpl(gs);
}
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xs.XSLoader#loadURI(java.lang.String)
*/
public XSModel loadURI(String uri) {
try {
Grammar g = loadGrammar(new XMLInputSource(null, uri, null));
return ((XSGrammar)g).toXSModel();
}
catch (Exception e){
reportDOMFatalError(e);
return null;
}
}
/* (non-Javadoc)
* @see com.sun.org.apache.xerces.internal.xs.XSLoader#loadURIList(com.sun.org.apache.xerces.internal.xs.StringList)
*/
public XSModel loadURIList(StringList uriList) {
int length = uriList.getLength();
SchemaGrammar[] gs = new SchemaGrammar[length];
for (int i = 0; i < length; i++) {
try {
gs[i] =
(SchemaGrammar) loadGrammar(new XMLInputSource(null, uriList.item(i), null));
} catch (Exception e) {
reportDOMFatalError(e);
return null;
}
}
return new XSModelImpl(gs);
}
void reportDOMFatalError(Exception e) {
if (fErrorHandler != null) {
DOMErrorImpl error = new DOMErrorImpl();
error.fException = e;
error.fMessage = e.getMessage();
error.fSeverity = DOMError.SEVERITY_FATAL_ERROR;
fErrorHandler.getErrorHandler().handleError(error);
}
}
/* (non-Javadoc)
* @see DOMConfiguration#canSetParameter(String, Object)
*/
public boolean canSetParameter(String name, Object value) {
if(value instanceof Boolean){
if (name.equals(Constants.DOM_VALIDATE) ||
name.equals(SCHEMA_FULL_CHECKING) ||
name.equals(VALIDATE_ANNOTATIONS) ||
name.equals(CONTINUE_AFTER_FATAL_ERROR) ||
name.equals(ALLOW_JAVA_ENCODINGS) ||
name.equals(STANDARD_URI_CONFORMANT_FEATURE) ||
name.equals(GENERATE_SYNTHETIC_ANNOTATIONS) ||
name.equals(HONOUR_ALL_SCHEMALOCATIONS) ||
name.equals(NAMESPACE_GROWTH) ||
name.equals(TOLERATE_DUPLICATES) ||
name.equals(USE_SERVICE_MECHANISM)) {
return true;
}
return false;
}
if (name.equals(Constants.DOM_ERROR_HANDLER) ||
name.equals(Constants.DOM_RESOURCE_RESOLVER) ||
name.equals(SYMBOL_TABLE) ||
name.equals(ERROR_REPORTER) ||
name.equals(ERROR_HANDLER) ||
name.equals(ENTITY_RESOLVER) ||
name.equals(XMLGRAMMAR_POOL) ||
name.equals(SCHEMA_LOCATION) ||
name.equals(SCHEMA_NONS_LOCATION) ||
name.equals(JAXP_SCHEMA_SOURCE) ||
name.equals(SCHEMA_DV_FACTORY)) {
return true;
}
return false;
}
/* (non-Javadoc)
* @see DOMConfiguration#getParameter(String)
*/
public Object getParameter(String name) throws DOMException {
if (name.equals(Constants.DOM_ERROR_HANDLER)){
return (fErrorHandler != null) ? fErrorHandler.getErrorHandler() : null;
}
else if (name.equals(Constants.DOM_RESOURCE_RESOLVER)) {
return (fResourceResolver != null) ? fResourceResolver.getEntityResolver() : null;
}
try {
boolean feature = getFeature(name);
return (feature) ? Boolean.TRUE : Boolean.FALSE;
} catch (Exception e) {
Object property;
try {
property = getProperty(name);
return property;
} catch (Exception ex) {
String msg =
DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN,
"FEATURE_NOT_SUPPORTED",
new Object[] { name });
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
}
}
}
/* (non-Javadoc)
* @see DOMConfiguration#getParameterNames()
*/
public DOMStringList getParameterNames() {
if (fRecognizedParameters == null){
Vector v = new Vector();
v.add(Constants.DOM_VALIDATE);
v.add(Constants.DOM_ERROR_HANDLER);
v.add(Constants.DOM_RESOURCE_RESOLVER);
v.add(SYMBOL_TABLE);
v.add(ERROR_REPORTER);
v.add(ERROR_HANDLER);
v.add(ENTITY_RESOLVER);
v.add(XMLGRAMMAR_POOL);
v.add(SCHEMA_LOCATION);
v.add(SCHEMA_NONS_LOCATION);
v.add(JAXP_SCHEMA_SOURCE);
v.add(SCHEMA_FULL_CHECKING);
v.add(CONTINUE_AFTER_FATAL_ERROR);
v.add(ALLOW_JAVA_ENCODINGS);
v.add(STANDARD_URI_CONFORMANT_FEATURE);
v.add(VALIDATE_ANNOTATIONS);
v.add(GENERATE_SYNTHETIC_ANNOTATIONS);
v.add(HONOUR_ALL_SCHEMALOCATIONS);
v.add(NAMESPACE_GROWTH);
v.add(TOLERATE_DUPLICATES);
v.add(USE_SERVICE_MECHANISM);
fRecognizedParameters = new DOMStringListImpl(v);
}
return fRecognizedParameters;
}
/* (non-Javadoc)
* @see DOMConfiguration#setParameter(String, Object)
*/
public void setParameter(String name, Object value) throws DOMException {
if (value instanceof Boolean) {
boolean state = ((Boolean) value).booleanValue();
if (name.equals("validate") && state) {
return;
}
try {
setFeature(name, state);
} catch (Exception e) {
String msg =
DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN,
"FEATURE_NOT_SUPPORTED",
new Object[] { name });
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
}
return;
}
if (name.equals(Constants.DOM_ERROR_HANDLER)) {
if (value instanceof DOMErrorHandler) {
try {
fErrorHandler = new DOMErrorHandlerWrapper((DOMErrorHandler) value);
setErrorHandler(fErrorHandler);
} catch (XMLConfigurationException e) {
}
} else {
// REVISIT: type mismatch
String msg =
DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN,
"FEATURE_NOT_SUPPORTED",
new Object[] { name });
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
}
return;
}
if (name.equals(Constants.DOM_RESOURCE_RESOLVER)) {
if (value instanceof LSResourceResolver) {
try {
fResourceResolver = new DOMEntityResolverWrapper((LSResourceResolver) value);
setEntityResolver(fResourceResolver);
}
catch (XMLConfigurationException e) {}
} else {
// REVISIT: type mismatch
String msg =
DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN,
"FEATURE_NOT_SUPPORTED",
new Object[] { name });
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
}
return;
}
try {
setProperty(name, value);
} catch (Exception ex) {
String msg =
DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN,
"FEATURE_NOT_SUPPORTED",
new Object[] { name });
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
}
}
XMLInputSource dom2xmlInputSource(LSInput is) {
// need to wrap the LSInput with an XMLInputSource
XMLInputSource xis = null;
/**
* An LSParser looks at inputs specified in LSInput in
* the following order: characterStream, byteStream,
* stringData, systemId, publicId. For consistency
* have the same behaviour for XSLoader.
*/
// check whether there is a Reader
// according to DOM, we need to treat such reader as "UTF-16".
if (is.getCharacterStream() != null) {
xis = new XMLInputSource(is.getPublicId(), is.getSystemId(),
is.getBaseURI(), is.getCharacterStream(),
"UTF-16");
}
// check whether there is an InputStream
else if (is.getByteStream() != null) {
xis = new XMLInputSource(is.getPublicId(), is.getSystemId(),
is.getBaseURI(), is.getByteStream(),
is.getEncoding());
}
// if there is a string data, use a StringReader
// according to DOM, we need to treat such data as "UTF-16".
else if (is.getStringData() != null && is.getStringData().length() != 0) {
xis = new XMLInputSource(is.getPublicId(), is.getSystemId(),
is.getBaseURI(), new StringReader(is.getStringData()),
"UTF-16");
}
// otherwise, just use the public/system/base Ids
else {
xis = new XMLInputSource(is.getPublicId(), is.getSystemId(),
is.getBaseURI());
}
return xis;
}
} // XMLGrammarLoader