|
|
|
|
|
*/ |
|
/* |
|
* Licensed to the Apache Software Foundation (ASF) under one or more |
|
* contributor license agreements. See the NOTICE file distributed with |
|
* this work for additional information regarding copyright ownership. |
|
* The ASF licenses this file to You 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.dtd; |
|
|
|
import java.io.EOFException; |
|
import java.io.IOException; |
|
import java.io.StringReader; |
|
import java.util.Locale; |
|
|
|
import com.sun.org.apache.xerces.internal.impl.Constants; |
|
import com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl; |
|
import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter; |
|
import com.sun.org.apache.xerces.internal.impl.XMLEntityManager; |
|
import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter; |
|
|
|
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.DefaultErrorHandler; |
|
|
|
import com.sun.org.apache.xerces.internal.xni.XNIException; |
|
import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool; |
|
import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarLoader; |
|
import com.sun.org.apache.xerces.internal.xni.grammars.Grammar; |
|
import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; |
|
import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler; |
|
import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver; |
|
import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public class XMLDTDLoader |
|
extends XMLDTDProcessor |
|
implements XMLGrammarLoader { |
|
|
|
// |
|
// Constants |
|
// |
|
|
|
// feature identifiers |
|
|
|
|
|
protected static final String STANDARD_URI_CONFORMANT_FEATURE = |
|
Constants.XERCES_FEATURE_PREFIX + Constants.STANDARD_URI_CONFORMANT_FEATURE; |
|
|
|
|
|
protected static final String BALANCE_SYNTAX_TREES = |
|
Constants.XERCES_FEATURE_PREFIX + Constants.BALANCE_SYNTAX_TREES; |
|
|
|
|
|
private static final String[] LOADER_RECOGNIZED_FEATURES = { |
|
VALIDATION, |
|
WARN_ON_DUPLICATE_ATTDEF, |
|
WARN_ON_UNDECLARED_ELEMDEF, |
|
NOTIFY_CHAR_REFS, |
|
STANDARD_URI_CONFORMANT_FEATURE, |
|
BALANCE_SYNTAX_TREES |
|
}; |
|
|
|
// property identifiers |
|
|
|
|
|
protected static final String ERROR_HANDLER = |
|
Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_HANDLER_PROPERTY; |
|
|
|
|
|
public static final String ENTITY_RESOLVER = |
|
Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY; |
|
|
|
|
|
public static final String LOCALE = |
|
Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY; |
|
|
|
|
|
private static final String[] LOADER_RECOGNIZED_PROPERTIES = { |
|
SYMBOL_TABLE, |
|
ERROR_REPORTER, |
|
ERROR_HANDLER, |
|
ENTITY_RESOLVER, |
|
GRAMMAR_POOL, |
|
DTD_VALIDATOR, |
|
LOCALE |
|
}; |
|
|
|
|
|
private boolean fStrictURI = false; |
|
|
|
|
|
private boolean fBalanceSyntaxTrees = false; |
|
|
|
|
|
protected XMLEntityResolver fEntityResolver; |
|
|
|
|
|
protected XMLDTDScannerImpl fDTDScanner; |
|
|
|
|
|
protected XMLEntityManager fEntityManager; |
|
|
|
|
|
protected Locale fLocale; |
|
|
|
// |
|
// Constructors |
|
// |
|
|
|
|
|
public XMLDTDLoader() { |
|
this(new SymbolTable()); |
|
} // <init>() |
|
|
|
public XMLDTDLoader(SymbolTable symbolTable) { |
|
this(symbolTable, null); |
|
} // init(SymbolTable) |
|
|
|
public XMLDTDLoader(SymbolTable symbolTable, |
|
XMLGrammarPool grammarPool) { |
|
this(symbolTable, grammarPool, null, new XMLEntityManager()); |
|
} // init(SymbolTable, XMLGrammarPool) |
|
|
|
XMLDTDLoader(SymbolTable symbolTable, |
|
XMLGrammarPool grammarPool, XMLErrorReporter errorReporter, |
|
XMLEntityResolver entityResolver) { |
|
fSymbolTable = symbolTable; |
|
fGrammarPool = grammarPool; |
|
if(errorReporter == null) { |
|
errorReporter = new XMLErrorReporter(); |
|
errorReporter.setProperty(ERROR_HANDLER, new DefaultErrorHandler()); |
|
} |
|
fErrorReporter = errorReporter; |
|
|
|
if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) { |
|
XMLMessageFormatter xmft = new XMLMessageFormatter(); |
|
fErrorReporter.putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, xmft); |
|
fErrorReporter.putMessageFormatter(XMLMessageFormatter.XMLNS_DOMAIN, xmft); |
|
} |
|
fEntityResolver = entityResolver; |
|
if(fEntityResolver instanceof XMLEntityManager) { |
|
fEntityManager = (XMLEntityManager)fEntityResolver; |
|
} else { |
|
fEntityManager = new XMLEntityManager(); |
|
} |
|
fEntityManager.setProperty(Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY, errorReporter); |
|
fDTDScanner = createDTDScanner(fSymbolTable, fErrorReporter, fEntityManager); |
|
fDTDScanner.setDTDHandler(this); |
|
fDTDScanner.setDTDContentModelHandler(this); |
|
reset(); |
|
} // init(SymbolTable, XMLGrammarPool, XMLErrorReporter, XMLEntityResolver) |
|
|
|
// XMLGrammarLoader methods |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public String[] getRecognizedFeatures() { |
|
return LOADER_RECOGNIZED_FEATURES.clone(); |
|
} // getRecognizedFeatures():String[] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public void setFeature(String featureId, boolean state) |
|
throws XMLConfigurationException { |
|
if (featureId.equals(VALIDATION)) { |
|
fValidation = state; |
|
} |
|
else if (featureId.equals(WARN_ON_DUPLICATE_ATTDEF)) { |
|
fWarnDuplicateAttdef = state; |
|
} |
|
else if (featureId.equals(WARN_ON_UNDECLARED_ELEMDEF)) { |
|
fWarnOnUndeclaredElemdef = state; |
|
} |
|
else if (featureId.equals(NOTIFY_CHAR_REFS)) { |
|
fDTDScanner.setFeature(featureId, state); |
|
} |
|
else if (featureId.equals(STANDARD_URI_CONFORMANT_FEATURE)) { |
|
fStrictURI = state; |
|
} |
|
else if (featureId.equals(BALANCE_SYNTAX_TREES)) { |
|
fBalanceSyntaxTrees = state; |
|
} |
|
else { |
|
throw new XMLConfigurationException(Status.NOT_RECOGNIZED, featureId); |
|
} |
|
} // setFeature(String,boolean) |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public String[] getRecognizedProperties() { |
|
return LOADER_RECOGNIZED_PROPERTIES.clone(); |
|
} // getRecognizedProperties():String[] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public Object getProperty(String propertyId) |
|
throws XMLConfigurationException { |
|
if (propertyId.equals(SYMBOL_TABLE)) { |
|
return fSymbolTable; |
|
} |
|
else if (propertyId.equals(ERROR_REPORTER)) { |
|
return fErrorReporter; |
|
} |
|
else if (propertyId.equals(ERROR_HANDLER)) { |
|
return fErrorReporter.getErrorHandler(); |
|
} |
|
else if (propertyId.equals(ENTITY_RESOLVER)) { |
|
return fEntityResolver; |
|
} |
|
else if (propertyId.equals(LOCALE)) { |
|
return getLocale(); |
|
} |
|
else if (propertyId.equals(GRAMMAR_POOL)) { |
|
return fGrammarPool; |
|
} |
|
else if (propertyId.equals(DTD_VALIDATOR)) { |
|
return fValidator; |
|
} |
|
throw new XMLConfigurationException(Status.NOT_RECOGNIZED, propertyId); |
|
} // getProperty(String): Object |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public void setProperty(String propertyId, Object value) |
|
throws XMLConfigurationException { |
|
if (propertyId.equals(SYMBOL_TABLE)) { |
|
fSymbolTable = (SymbolTable)value; |
|
fDTDScanner.setProperty(propertyId, value); |
|
fEntityManager.setProperty(propertyId, value); |
|
} |
|
else if(propertyId.equals(ERROR_REPORTER)) { |
|
fErrorReporter = (XMLErrorReporter)value; |
|
|
|
if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) { |
|
XMLMessageFormatter xmft = new XMLMessageFormatter(); |
|
fErrorReporter.putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, xmft); |
|
fErrorReporter.putMessageFormatter(XMLMessageFormatter.XMLNS_DOMAIN, xmft); |
|
} |
|
fDTDScanner.setProperty(propertyId, value); |
|
fEntityManager.setProperty(propertyId, value); |
|
} |
|
else if (propertyId.equals(ERROR_HANDLER)) { |
|
fErrorReporter.setProperty(propertyId, value); |
|
} |
|
else if (propertyId.equals(ENTITY_RESOLVER)) { |
|
fEntityResolver = (XMLEntityResolver)value; |
|
fEntityManager.setProperty(propertyId, value); |
|
} |
|
else if (propertyId.equals(LOCALE)) { |
|
setLocale((Locale) value); |
|
} |
|
else if(propertyId.equals(GRAMMAR_POOL)) { |
|
fGrammarPool = (XMLGrammarPool)value; |
|
} |
|
else { |
|
throw new XMLConfigurationException(Status.NOT_RECOGNIZED, propertyId); |
|
} |
|
} // setProperty(String,Object) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public boolean getFeature(String featureId) |
|
throws XMLConfigurationException { |
|
if (featureId.equals(VALIDATION)) { |
|
return fValidation; |
|
} |
|
else if (featureId.equals(WARN_ON_DUPLICATE_ATTDEF)) { |
|
return fWarnDuplicateAttdef; |
|
} |
|
else if (featureId.equals(WARN_ON_UNDECLARED_ELEMDEF)) { |
|
return fWarnOnUndeclaredElemdef; |
|
} |
|
else if (featureId.equals(NOTIFY_CHAR_REFS)) { |
|
return fDTDScanner.getFeature(featureId); |
|
} |
|
else if (featureId.equals(STANDARD_URI_CONFORMANT_FEATURE)) { |
|
return fStrictURI; |
|
} |
|
else if (featureId.equals(BALANCE_SYNTAX_TREES)) { |
|
return fBalanceSyntaxTrees; |
|
} |
|
throw new XMLConfigurationException(Status.NOT_RECOGNIZED, featureId); |
|
} //getFeature(String): boolean |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public void setLocale(Locale locale) { |
|
fLocale = locale; |
|
fErrorReporter.setLocale(locale); |
|
} // setLocale(Locale) |
|
|
|
|
|
public Locale getLocale() { |
|
return fLocale; |
|
} // getLocale(): Locale |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public void setErrorHandler(XMLErrorHandler errorHandler) { |
|
fErrorReporter.setProperty(ERROR_HANDLER, errorHandler); |
|
} // setErrorHandler(XMLErrorHandler) |
|
|
|
|
|
public XMLErrorHandler getErrorHandler() { |
|
return fErrorReporter.getErrorHandler(); |
|
} // getErrorHandler(): XMLErrorHandler |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public void setEntityResolver(XMLEntityResolver entityResolver) { |
|
fEntityResolver = entityResolver; |
|
fEntityManager.setProperty(ENTITY_RESOLVER, entityResolver); |
|
} // setEntityResolver(XMLEntityResolver) |
|
|
|
|
|
public XMLEntityResolver getEntityResolver() { |
|
return fEntityResolver; |
|
} // getEntityResolver(): XMLEntityResolver |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public Grammar loadGrammar(XMLInputSource source) |
|
throws IOException, XNIException { |
|
reset(); |
|
|
|
String eid = XMLEntityManager.expandSystemId(source.getSystemId(), source.getBaseSystemId(), fStrictURI); |
|
XMLDTDDescription desc = new XMLDTDDescription(source.getPublicId(), source.getSystemId(), source.getBaseSystemId(), eid, null); |
|
if (!fBalanceSyntaxTrees) { |
|
fDTDGrammar = new DTDGrammar(fSymbolTable, desc); |
|
} |
|
else { |
|
fDTDGrammar = new BalancedDTDGrammar(fSymbolTable, desc); |
|
} |
|
fGrammarBucket = new DTDGrammarBucket(); |
|
fGrammarBucket.setStandalone(false); |
|
fGrammarBucket.setActiveGrammar(fDTDGrammar); |
|
// no reason to use grammar bucket's "put" method--we |
|
// know which grammar it is, and we don't know the root name anyway... |
|
|
|
|
|
try { |
|
fDTDScanner.setInputSource(source); |
|
fDTDScanner.scanDTDExternalSubset(true); |
|
} catch (EOFException e) { |
|
// expected behaviour... |
|
} |
|
finally { |
|
|
|
fEntityManager.closeReaders(); |
|
} |
|
if(fDTDGrammar != null && fGrammarPool != null) { |
|
fGrammarPool.cacheGrammars(XMLDTDDescription.XML_DTD, new Grammar[] {fDTDGrammar}); |
|
} |
|
return fDTDGrammar; |
|
} // loadGrammar(XMLInputSource): Grammar |
|
|
|
|
|
|
|
|
|
*/ |
|
public void loadGrammarWithContext(XMLDTDValidator validator, String rootName, |
|
String publicId, String systemId, String baseSystemId, String internalSubset) |
|
throws IOException, XNIException { |
|
final DTDGrammarBucket grammarBucket = validator.getGrammarBucket(); |
|
final DTDGrammar activeGrammar = grammarBucket.getActiveGrammar(); |
|
if (activeGrammar != null && !activeGrammar.isImmutable()) { |
|
fGrammarBucket = grammarBucket; |
|
fEntityManager.setScannerVersion(getScannerVersion()); |
|
reset(); |
|
try { |
|
|
|
if (internalSubset != null) { |
|
// To get the DTD scanner to end at the right place we have to fool |
|
// it into thinking that it reached the end of the internal subset |
|
|
|
StringBuffer buffer = new StringBuffer(internalSubset.length() + 2); |
|
buffer.append(internalSubset).append("]>"); |
|
XMLInputSource is = new XMLInputSource(null, baseSystemId, |
|
null, new StringReader(buffer.toString()), null); |
|
fEntityManager.startDocumentEntity(is); |
|
fDTDScanner.scanDTDInternalSubset(true, false, systemId != null); |
|
} |
|
|
|
if (systemId != null) { |
|
XMLDTDDescription desc = new XMLDTDDescription(publicId, systemId, baseSystemId, null, rootName); |
|
XMLInputSource source = fEntityManager.resolveEntity(desc); |
|
fDTDScanner.setInputSource(source); |
|
fDTDScanner.scanDTDExternalSubset(true); |
|
} |
|
} |
|
catch (EOFException e) { |
|
// expected behaviour... |
|
} |
|
finally { |
|
|
|
fEntityManager.closeReaders(); |
|
} |
|
} |
|
} // loadGrammarWithContext(XMLDTDValidator, String, String, String, String, String) |
|
|
|
|
|
protected void reset() { |
|
super.reset(); |
|
fDTDScanner.reset(); |
|
fEntityManager.reset(); |
|
fErrorReporter.setDocumentLocator(fEntityManager.getEntityScanner()); |
|
} |
|
|
|
protected XMLDTDScannerImpl createDTDScanner(SymbolTable symbolTable, |
|
XMLErrorReporter errorReporter, XMLEntityManager entityManager) { |
|
return new XMLDTDScannerImpl(symbolTable, errorReporter, entityManager); |
|
} // createDTDScanner(SymbolTable, XMLErrorReporter, XMLEntityManager) : XMLDTDScannerImpl |
|
|
|
protected short getScannerVersion() { |
|
return Constants.XML_VERSION_1_0; |
|
} // getScannerVersion() : short |
|
|
|
} // class XMLDTDLoader |