/*
*/
/*
* Copyright 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
*
*
* 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.
*/
/**
* Will keep track of current entity.
*
* The entity manager handles the registration of general and parameter
* entities; resolves entities; and starts entities. The entity manager
* is a central component in a standard parser configuration and this
* class works directly with the entity scanner to manage the underlying
* xni.
* <p>
* This component requires the following features and properties from the
* component manager that uses it:
* <ul>
* <li>http://xml.org/sax/features/validation</li>
* </ul>
*
*
* @author Andy Clark, IBM
* @author Arnaud Le Hors, IBM
* @author K.Venugopal SUN Microsystems
* @author Neeraj Bajaj SUN Microsystems
* @author Sunitha Reddy SUN Microsystems
* @version $Id: XMLEntityManager.java,v 1.17 2010-11-01 04:39:41 joehw Exp $
*/
//
// Constants
//
/** Default buffer size (2048). */
/** Default buffer size before we've finished with the XMLDecl: */
/** Default internal entity buffer size (1024). */
// feature identifiers
/** Feature identifier: validation. */
/**
* standard uri conformant (strict uri).
*/
protected boolean fStrictURI;
/** Feature identifier: external general entities. */
/** Feature identifier: external parameter entities. */
/** Feature identifier: allow Java encodings. */
/** Feature identifier: warn on duplicate EntityDef */
/** Feature identifier: load external DTD. */
// property identifiers
/** Property identifier: symbol table. */
/** Property identifier: error reporter. */
/** Feature identifier: standard uri conformant */
/** Property identifier: entity resolver. */
// property identifier: ValidationManager
/** property identifier: buffer size. */
/** property identifier: security manager. */
/** property identifier: access external dtd. */
/** access external dtd: file protocol */
// recognized features and properties
/** Recognized features. */
};
/** Feature defaults. */
null,
};
/** Recognized properties. */
};
/** Property defaults. */
null,
null,
null,
null,
new Integer(DEFAULT_BUFFER_SIZE),
null,
};
// debugging
/**
* Debug printing of buffer. This debugging flag works best when you
* resize the DEFAULT_BUFFER_SIZE down to something reasonable like
* 64 characters.
*/
private static final boolean DEBUG_BUFFER = false;
/** warn on duplicate Entity declaration.
*/
protected boolean fWarnDuplicateEntityDef;
/** Debug some basic entities. */
private static final boolean DEBUG_ENTITIES = false;
/** Debug switching readers for encodings. */
private static final boolean DEBUG_ENCODINGS = false;
// should be diplayed trace resolving messages
private static final boolean DEBUG_RESOLVER = false ;
//
// Data
//
// features
/**
* Validation. This feature identifier is:
*/
protected boolean fValidation;
/**
* External general entities. This feature identifier is:
*/
protected boolean fExternalGeneralEntities;
/**
* External parameter entities. This feature identifier is:
*/
protected boolean fExternalParameterEntities;
/**
* Allow Java encoding names. This feature identifier is:
*/
protected boolean fAllowJavaEncodings = true ;
/** Load external DTD. */
protected boolean fLoadExternalDTD = true;
// properties
/**
* Symbol table. This property identifier is:
*/
/**
* Error reporter. This property identifier is:
*/
/**
* Entity resolver. This property identifier is:
*/
/** Stax Entity Resolver. This property identifier is XMLInputFactory.ENTITY_RESOLVER */
/** Property Manager. This is used from Stax */
/** used to restrict external access */
// settings
/**
* Validation manager. This property identifier is:
*/
// settings
/**
* Buffer size. We get this value from a property. The default size
* is used if the input buffer size property is not specified.
* REVISIT: do we need a property for internal entity buffer size?
*/
// stores defaults for entity expansion limit if it has
// been set on the configuration.
/**
* True if the document entity is standalone. This should really
* only be set by the document source (e.g. XMLDocumentScanner).
*/
protected boolean fStandalone;
// are the entities being parsed in the external subset?
// NOTE: this *is not* the same as whether they're external entities!
protected boolean fInExternalSubset = false;
// handlers
/** Entity handler. */
/** Current entity scanner */
/** XML 1.0 entity scanner. */
/** XML 1.1 entity scanner. */
/** entity expansion limit (contains useful data if and only if
fSecurityManager is non-null) */
/** count of entities expanded: */
// entities
/** Entities. */
/** Entity stack. */
/** Current entity. */
/** identify if the InputSource is created by a resolver */
boolean fISCreatedByResolver = false;
// shared context
// temp vars
/** Resource identifer. */
/** Augmentations for entities. */
/** Pool of character buffers. */
private CharacterBufferPool fBufferPool = new CharacterBufferPool(fBufferSize, DEFAULT_INTERNAL_BUFFER_SIZE);
//
// Constructors
//
/**
* If this constructor is used to create the object, reset() should be invoked on this object
*/
public XMLEntityManager() {
fEntityStorage = new XMLEntityStorage(this) ;
} // <init>()
/** Default constructor. */
//pass a reference to current entity being scanned
//fEntityStorage = new XMLEntityStorage(fCurrentEntity) ;
fEntityStorage = new XMLEntityStorage(this) ;
} // <init>()
/**
* Adds an internal entity declaration.
* <p>
* <strong>Note:</strong> This method ignores subsequent entity
* declarations.
* <p>
* <strong>Note:</strong> The name should be a unique symbol. The
* SymbolTable can be used for this purpose.
*
* @param name The name of the entity.
* @param text The text of the entity.
*
* @see SymbolTable
*/
} else{
"MSG_DUPLICATE_ENTITY_DEFINITION",
}
}
} // addInternalEntity(String,String)
/**
* Adds an external entity declaration.
* <p>
* <strong>Note:</strong> This method ignores subsequent entity
* declarations.
* <p>
* <strong>Note:</strong> The name should be a unique symbol. The
* SymbolTable can be used for this purpose.
*
* @param name The name of the entity.
* @param publicId The public identifier of the entity.
* @param literalSystemId The system identifier of the entity.
* @param baseSystemId The base system identifier of the entity.
* This is the system identifier of the entity
* where <em>the entity being added</em> and
* is used to expand the system identifier when
* the system identifier is a relative URI.
* When null the system identifier of the first
* external entity on the stack is used instead.
*
* @see SymbolTable
*/
if (baseSystemId == null) {
// search for the first external entity on the stack
}
if (externalEntity.entityLocation != null && externalEntity.entityLocation.getExpandedSystemId() != null) {
break;
}
}
}
} else{
"MSG_DUPLICATE_ENTITY_DEFINITION",
}
}
} // addExternalEntity(String,String,String,String)
/**
* Adds an unparsed entity declaration.
* <p>
* <strong>Note:</strong> This method ignores subsequent entity
* declarations.
* <p>
* <strong>Note:</strong> The name should be a unique symbol. The
* SymbolTable can be used for this purpose.
*
* @param name The name of the entity.
* @param publicId The public identifier of the entity.
* @param systemId The system identifier of the entity.
* @param notation The name of the notation.
*
* @see SymbolTable
*/
} else{
"MSG_DUPLICATE_ENTITY_DEFINITION",
}
}
} // addUnparsedEntity(String,String,String,String)
/** get the entity storage object from entity manager */
return fEntityStorage ;
}
/** return the entity responsible for reading the entity */
if(fEntityScanner == null) {
// default to 1.0
if(fXML10EntityScanner == null) {
fXML10EntityScanner = new XMLEntityScanner();
}
}
return fEntityScanner;
}
if(fXML10EntityScanner == null) {
fXML10EntityScanner = new XMLEntityScanner();
}
} else {
if(fXML11EntityScanner == null) {
fXML11EntityScanner = new XML11EntityScanner();
}
}
}
/**
* This method uses the passed-in XMLInputSource to make
* fCurrentEntity usable for reading.
* @param name name of the entity (XML is it's the document entity)
* @param xmlInputSource the input source, with sufficient information
* to begin scanning characters.
* @param literal True if this entity is started within a
* literal value.
* @param isExternal whether this entity should be treated as an internal or external entity.
* @throws IOException if anything can't be read
* XNIException If any parser-specific goes wrong.
* @return the encoding of the new entity or null if a character stream was employed
*/
boolean literal, boolean isExternal)
throws IOException, XNIException {
// get information
// create reader
// First chance checking strict URI
if (baseSystemId == null) {
}
if (!(connect instanceof HttpURLConnection)) {
}
else {
boolean followRedirects = true;
// setup URLConnection if we have an HTTPInputSource
if (xmlInputSource instanceof HTTPInputSource) {
// set request properties
}
// set preference for redirection
if (!followRedirects) {
}
}
// REVISIT: If the URLConnection has external encoding
// information, we should be reading it here. It's located
// in the charset parameter of Content-Type. -- mrglavas
if (followRedirects) {
// E43: Check if the URL was redirected, and then
// update literal and expanded system IDs if needed.
}
}
}
}
// wrap this stream in RewindableInputStream
// perform auto-detect of encoding if necessary
// read first four bytes and determine encoding
final byte[] b4 = new byte[4];
int count = 0;
}
if (count == 4) {
// Special case UTF-8 files with BOM created by Microsoft
// tools. It's more efficient to consume the BOM than make
// the reader perform extra checks. -Ac
// ignore first three bytes...
}
}
} else {
}
}
// use specified encoding
else {
// If encoding is UTF-8, consume BOM if one is present.
final int[] b3 = new int[3];
int count = 0;
break;
}
if (count == 3) {
// First three bytes are not BOM, so reset.
}
} else {
}
}
// If encoding is UTF-16, we still need to read the first four bytes
// in order to discover the byte order.
final int[] b4 = new int[4];
int count = 0;
break;
}
if (count >= 2) {
// UTF-16, big-endian
utf16Encoding = "UTF-16BE";
}
// UTF-16, little-endian
utf16Encoding = "UTF-16LE";
}
else if (count == 4) {
// UTF-16, big-endian, no BOM
utf16Encoding = "UTF-16BE";
}
// UTF-16, little-endian, no BOM
utf16Encoding = "UTF-16LE";
}
}
}
}
// If encoding is UCS-4, we still need to read the first four bytes
// in order to discover the byte order.
final int[] b4 = new int[4];
int count = 0;
break;
}
// Ignore unusual octet order for now.
if (count == 4) {
// UCS-4, big endian (1234)
}
// UCS-4, little endian (1234)
}
}
}
// If encoding is UCS-2, we still need to read the first four bytes
// in order to discover the byte order.
final int[] b4 = new int[4];
int count = 0;
break;
}
if (count == 4) {
// UCS-2, big endian
}
// UCS-2, little endian
}
}
}
}
// read one character at a time so we don't jump too far
// ahead, converting characters from the byte stream in
// the wrong encoding
if (DEBUG_ENCODINGS) {
}
//reader = new OneCharReader(reader);
}
// We've seen a new Reader.
// Push it on the stack so we can close it later.
//fOwnReaders.add(reader);
// push entity on stack
if (fCurrentEntity != null) {
}
// create entity
/* if encoding is specified externally, 'encoding' information present
* in the prolog of the XML document is not considered. Hence, prolog can
* be read in Chunks of data instead of byte by byte.
*/
fCurrentEntity = new com.sun.xml.internal.stream.Entity.ScannedEntity(name,new XMLResourceIdentifierImpl(publicId, literalSystemId, baseSystemId, expandedSystemId),stream, reader, encoding, literal, encodingExternallySpecified, isExternal);
return encoding;
} //setupCurrentEntity(String, XMLInputSource, boolean, boolean): String
/**
* Checks whether an entity given by name is external.
*
* @param entityName The name of the entity to check.
* @return True if the entity is external, false otherwise
* (including when the entity is not declared).
*/
return false;
}
return entity.isExternal();
}
/**
* Checks whether the declaration of an entity given by name is
* // in the external subset.
*
* @param entityName The name of the entity to check.
* @return True if the entity was declared in the external subset, false otherwise
* (including when the entity is not declared).
*/
return false;
}
return entity.isEntityDeclInExternalSubset();
}
//
// Public methods
//
/**
* Sets whether the document entity is standalone.
*
* @param standalone True if document entity is standalone.
*/
}
// setStandalone(boolean)
/** Returns true if the document entity is standalone. */
public boolean isStandalone() {
return fStandalone;
} //isStandalone():boolean
}
return false;
}
return entity.isUnparsed();
}
// this simply returns the fResourceIdentifier object;
// this should only be used with caution by callers that
// carefully manage the entity manager's behaviour, so that
// this doesn't returning meaningless or misleading data.
// @return a reference to the current fResourceIdentifier object
return fResourceIdentifier;
}
/**
* Sets the entity handler. When an entity starts and ends, the
* entity handler is notified of the change.
*
* @param entityHandler The new entity handler.
*/
public void setEntityHandler(com.sun.org.apache.xerces.internal.impl.XMLEntityHandler entityHandler) {
} // setEntityHandler(XMLEntityHandler)
//this function returns StaxXMLInputSource
public StaxXMLInputSource resolveEntityAsPerStax(XMLResourceIdentifier resourceIdentifier) throws java.io.IOException{
// if no base systemId given, assume that it's relative
// to the systemId of the current scanned entity
// Sometimes the system id is not (properly) expanded.
// We need to expand the system id if:
// a. the expanded one was null; or
// b. the base system id was null, but becomes non-null from the current entity.
// REVISIT: why would the baseSystemId ever be null? if we
// didn't have to make this check we wouldn't have to reuse the
// fXMLResourceIdentifier object...
if (baseSystemId != null)
needExpand = true;
}
if (needExpand)
// give the entity resolver a chance
if (resourceIdentifier instanceof XMLResourceIdentifierImpl) {
} else {
}
if(DEBUG_RESOLVER){
}
fISCreatedByResolver = false;
//either of Stax or Xerces would be null
if(fStaxEntityResolver != null){
if(staxInputSource != null) {
fISCreatedByResolver = true;
}
}
if(fEntityResolver != null){
if(xmlInputSource != null) {
fISCreatedByResolver = true;
}
}
if(xmlInputSource != null){
//wrap this XMLInputSource to StaxInputSource
}
// do default resolution
//this works for both stax & Xerces, if staxInputSource is null, it means parser need to revert to default resolution
if (staxInputSource == null) {
// REVISIT: when systemId is null, I think we should return null.
// is this the right solution? -SG
//if (systemId != null)
staxInputSource = new StaxXMLInputSource(new XMLInputSource(publicId, literalSystemId, baseSystemId));
}else if(staxInputSource.hasXMLStreamOrXMLEventReader()){
//Waiting for the clarification from EG. - nb
}
if (DEBUG_RESOLVER) {
}
return staxInputSource;
}
/**
* Resolves the specified public and system identifiers. This
* method first attempts to resolve the entity based on the
* EntityResolver registered by the application. If no entity
* resolver is registered or if the registered entity handler
* is unable to resolve the entity, then default entity
* resolution will occur.
*
* @param publicId The public identifier of the entity.
* @param systemId The system identifier of the entity.
* @param baseSystemId The base system identifier of the entity.
* This is the system identifier of the current
* entity and is used to expand the system
* identifier when the system identifier is a
* relative URI.
*
* @return Returns an input source that wraps the resolved entity.
* This method will never return null.
*
* @throws IOException Thrown on i/o error.
* @throws XNIException Thrown by entity resolver to signal an error.
*/
public XMLInputSource resolveEntity(XMLResourceIdentifier resourceIdentifier) throws IOException, XNIException {
// if no base systemId given, assume that it's relative
// to the systemId of the current scanned entity
// Sometimes the system id is not (properly) expanded.
// We need to expand the system id if:
// a. the expanded one was null; or
// b. the base system id was null, but becomes non-null from the current entity.
// REVISIT: why would the baseSystemId ever be null? if we
// didn't have to make this check we wouldn't have to reuse the
// fXMLResourceIdentifier object...
if (baseSystemId != null)
needExpand = true;
}
if (needExpand)
// give the entity resolver a chance
if (fEntityResolver != null) {
}
// do default resolution
// REVISIT: what's the correct behavior if the user provided an entity
// resolver (fEntityResolver != null), but resolveEntity doesn't return
// an input source (xmlInputSource == null)?
// do we do default resolution, or do we just return null? -SG
if (xmlInputSource == null) {
// REVISIT: when systemId is null, I think we should return null.
// is this the right solution? -SG
//if (systemId != null)
}
if (DEBUG_RESOLVER) {
}
return xmlInputSource;
} // resolveEntity(XMLResourceIdentifier):XMLInputSource
/**
* Starts a named entity.
*
* @param entityName The name of the entity to start.
* @param literal True if this entity is started within a literal
* value.
*
* @throws IOException Thrown on i/o error.
* @throws XNIException Thrown by entity handler to signal an error.
*/
throws IOException, XNIException {
// was entity declared?
if (fEntityHandler != null) {
}
return;
}
// should we skip external entities?
if (external) {
extLitSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getLiteralSystemId() : null);
extBaseSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getBaseSystemId() : null);
(parameter && !fExternalParameterEntities)) {
if (fEntityHandler != null) {
}
return;
}
}
// is entity recursive?
for (int i = size; i >= 0; i--) {
for (int j = i + 1; j < size; j++) {
}
"RecursiveReference",
if (fEntityHandler != null) {
if (external) {
}
}
return;
}
}
// resolve external entity
if (external) {
/** xxx: Waiting from the EG
* //simply return if there was entity resolver registered and application
* //returns either XMLStreamReader or XMLEventReader.
* if(staxInputSource.hasXMLStreamOrXMLEventReader()) return ;
*/
if (!fISCreatedByResolver) {
//let the not-LoadExternalDTD or not-SupportDTD process to handle the situation
if (fLoadExternalDTD) {
String accessError = SecuritySupport.checkAccess(expandedSystemId, fAccessExternalDTD, Constants.ACCESS_EXTERNAL_ALL);
if (accessError != null) {
"AccessExternalEntity",
}
}
}
}
// wrap internal entity
else {
}
// start the entity
} // startEntity(String,boolean)
/**
* Starts the document entity. The document entity has the "[xml]"
* pseudo-name.
*
* @param xmlInputSource The input source of the document entity.
*
* @throws IOException Thrown on i/o error.
* @throws XNIException Thrown by entity handler to signal an error.
*/
throws IOException, XNIException {
} // startDocumentEntity(XMLInputSource)
//xxx these methods are not required.
/**
* Starts the DTD entity. The DTD entity has the "[dtd]"
* pseudo-name.
*
* @param xmlInputSource The input source of the DTD entity.
*
* @throws IOException Thrown on i/o error.
* @throws XNIException Thrown by entity handler to signal an error.
*/
throws IOException, XNIException {
} // startDTDEntity(XMLInputSource)
// indicate start of external subset so that
// location of entity decls can be tracked
public void startExternalSubset() {
fInExternalSubset = true;
}
public void endExternalSubset() {
fInExternalSubset = false;
}
/**
* Starts an entity.
* <p>
* This method can be used to insert an application defined XML
* entity stream into the parsing stream.
*
* @param name The name of the entity.
* @param xmlInputSource The input source of the entity.
* @param literal True if this entity is started within a
* literal value.
* @param isExternal whether this entity should be treated as an internal or external entity.
*
* @throws IOException Thrown on i/o error.
* @throws XNIException Thrown by entity handler to signal an error.
*/
boolean literal, boolean isExternal)
throws IOException, XNIException {
//when entity expansion limit is set by the Application, we need to
//check for the entity expansion limit set by the parser, if number of entity
//expansions exceeds the entity expansion limit, parser will throw fatal error.
// Note that this represents the nesting level of open entities.
"EntityExpansionLimitExceeded",
// is there anything better to do than reset the counter?
// at least one can envision debugging applications where this might
// be useful...
}
// call handler
if (fEntityHandler != null) {
}
} // startEntity(String,XMLInputSource)
/**
* Return the current entity being scanned. Current entity is SET using startEntity function.
* @return Entity.ScannedEntity
*/
return fCurrentEntity ;
}
/**
* Return the top level entity handled by this manager, or null
* if no entity was added.
*/
return (Entity.ScannedEntity)
}
/**
* Close all opened InputStreams and Readers opened by this parser.
*/
public void closeReaders() {
/** this call actually does nothing, readers are closed in the endEntity method
* through the current entity.
* The change seems to have happened during the jdk6 development with the
* addition of StAX
**/
}
// call handler
if (DEBUG_BUFFER) {
print();
}
//pop the entity from the stack
Entity.ScannedEntity entity = fEntityStack.size() > 0 ? (Entity.ScannedEntity)fEntityStack.pop() : null ;
/** need to close the reader first since the program can end
* prematurely (e.g. fEntityHandler.endEntity may throw exception)
* leaving the reader open
*/
//close the reader
if(fCurrentEntity != null){
//close the reader
try{
}catch(IOException ex){
throw new XNIException(ex);
}
}
if (fEntityHandler != null) {
//so this is the last opened entity, signal it to current fEntityHandler using Augmentation
}else{
}
}
//check if it is a document entity
//set popped entity as current entity
//check if there are any entity left in the stack -- if there are
//no entries EOF has been reached.
// throw exception when it is the last entity but it is not a document entity
throw new EOFException() ;
}
if (DEBUG_BUFFER) {
print();
}
} // endEntity()
//
// XMLComponent methods
//
//reset fEntityStorage
//reset XMLEntityReaderImpl
// xerces properties
fSymbolTable = (SymbolTable)propertyManager.getProperty(Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY);
fErrorReporter = (XMLErrorReporter)propertyManager.getProperty(Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY);
try {
} catch (XMLConfigurationException e) {
}
// Zephyr feature ignore-external-dtd is the opposite of Xerces' load-external-dtd
fLoadExternalDTD = !((Boolean)propertyManager.getProperty(Constants.ZEPHYR_PROPERTY_PREFIX + Constants.IGNORE_EXTERNAL_DTD)).booleanValue();
// JAXP 1.5 feature
// initialize state
//fStandalone = false;
fValidation = false;
fExternalGeneralEntities = true;
fExternalParameterEntities = true;
fAllowJavaEncodings = true ;
}
/**
* Resets the component. The component can query the component manager
* about any features and properties that affect the operation of the
* component.
*
* @param componentManager The component manager.
*
* @throws SAXException Thrown by component on initialization error.
* For example, if a feature or property is
* required for the operation of the component, the
* component manager may throw a
* SAXNotRecognizedException or a
* SAXNotSupportedException.
*/
throws XMLConfigurationException {
if (!parser_settings) {
// parser settings have not been changed
reset();
if(fEntityScanner != null){
}
if(fEntityStorage != null){
}
return;
}
// sax features
// xerces features
// xerces properties
fStaxEntityResolver = (StaxEntityResolverWrapper)componentManager.getProperty(STAX_ENTITY_RESOLVER, null);
// JAXP 1.5 feature
fAccessExternalDTD = (String) componentManager.getProperty(ACCESS_EXTERNAL_DTD, EXTERNAL_ACCESS_DEFAULT);
//reset general state
reset();
} // reset(XMLComponentManager)
// reset general state. Should not be called other than by
// a class acting as a component manager but not
// implementing that interface for whatever reason.
public void reset() {
// initialize state
fStandalone = false;
// reset scanner
if(fXML10EntityScanner != null){
}
if(fXML11EntityScanner != null) {
}
// DEBUG
if (DEBUG_ENTITIES) {
try {
addExternalEntity("external-balanced-element", null, "external-balanced-element.ent", "test/external-balanced-element.xml");
}
catch (IOException ex) {
// should never happen
}
}
// reset scanner
//if(fEntityScanner!=null)
// fEntityScanner.reset(fSymbolTable, this,fErrorReporter);
}
/**
* Returns a list of feature identifiers that are recognized by
* this component. This method may return null if no features
* are recognized by this component.
*/
} // getRecognizedFeatures():String[]
/**
* Sets the state of a feature. This method is called by the component
* manager any time after reset when a feature changes state.
* <p>
* <strong>Note:</strong> Components should silently ignore features
* that do not affect the operation of the component.
*
* @param featureId The feature identifier.
* @param state The state of the feature.
*
* @throws SAXNotRecognizedException The component should not throw
* this exception.
* @throws SAXNotSupportedException The component should not throw
* this exception.
*/
throws XMLConfigurationException {
// xerces features
}
return;
}
}
} // setFeature(String,boolean)
/**
* Sets the value of a property. This method is called by the component
* manager any time after reset when a property changes value.
* <p>
* <strong>Note:</strong> Components should silently ignore properties
* that do not affect the operation of the component.
*
* @param propertyId The property identifier.
* @param value The value of the property.
*
* @throws SAXNotRecognizedException The component should not throw
* this exception.
* @throws SAXNotSupportedException The component should not throw
* this exception.
*/
// Xerces properties
return;
}
return;
}
return;
}
if (bufferSize != null &&
}
}
}
}
//JAXP 1.5 properties
{
}
}
}
/**
* Returns a list of property identifiers that are recognized by
* this component. This method may return null if no properties
* are recognized by this component.
*/
} // getRecognizedProperties():String[]
/**
* Returns the default state for a feature, or null if this
* component does not want to report a default value for this
* feature.
*
* @param featureId The feature identifier.
*
* @since Xerces 2.2.0
*/
return FEATURE_DEFAULTS[i];
}
}
return null;
} // getFeatureDefault(String):Boolean
/**
* Returns the default state for a property, or null if this
* component does not want to report a default value for this
* property.
*
* @param propertyId The property identifier.
*
* @since Xerces 2.2.0
*/
return PROPERTY_DEFAULTS[i];
}
}
return null;
} // getPropertyDefault(String):Object
//
// Public static methods
//
/**
* Expands a system id and returns the system id as a URI, if
* it can be expanded. A return value of null means that the
* identifier is already expanded. An exception thrown
* indicates a failure to expand the id.
*
* @param systemId The systemId to be expanded.
*
* @return Returns the URI string representing the expanded system
* identifier. A null value indicates that the given
* system identifier is already expanded.
*
*/
} // expandSystemId(String):String
//
// Public static methods
//
// current value of the "user.dir" property
// cached URI object for the current value of the escaped "user.dir" property stored as a URI
// which ASCII characters need to be escaped
// the first hex character if a character needs to be escaped
// the second hex character if a character needs to be escaped
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
// initialize the above 3 arrays
static {
for (int i = 0; i <= 0x1f; i++) {
gNeedEscaping[i] = true;
}
gNeedEscaping[0x7f] = true;
'|', '\\', '^', '~', '[', ']', '`'};
char ch;
for (int i = 0; i < len; i++) {
gNeedEscaping[ch] = true;
}
}
// To escape the "user.dir" system property, by using %HH to represent
// special ASCII characters: 0x00~0x1F, 0x7F, ' ', '<', '>', '#', '%'
// and '"'. It's a static method, so needs to be synchronized.
// this method looks heavy, but since the system property isn't expected
// to change often, so in most cases, we only need to return the URI
// that was escaped before.
// According to the URI spec, non-ASCII characters (whose value >= 128)
// need to be escaped too.
// REVISIT: don't know how to escape non-ASCII characters, especially
// which encoding to use. Leave them for now.
// get the user.dir property
try {
}
catch (SecurityException se) {
}
// return empty string if property value is empty string.
// compute the new escaped value if the new property value doesn't
// match the previous one
return gUserDirURI;
}
// record the new value as the global property value
// change C:/blah to /C:/blah
}
}
// for each character in the path
int i = 0;
for (; i < len; i++) {
// if it's not an ASCII character, break here, and use UTF-8 encoding
if (ch >= 128)
break;
if (gNeedEscaping[ch]) {
// record the fact that it's escaped
}
else {
}
}
// we saw some non-ascii character
if (i < len) {
// get UTF-8 bytes for the remaining sub-string
byte b;
try {
// should never happen
}
// for each byte
for (i = 0; i < len; i++) {
b = bytes[i];
// for non-ascii character: make it positive, then escape
if (b < 0) {
ch = b + 256;
}
else if (gNeedEscaping[b]) {
}
else {
}
}
}
return gUserDirURI;
}
/**
* Absolutizes a URI using the current value
* of the "user.dir" property as the base URI. If
* the URI is already absolute, this is a no-op.
*
* @param uri the URI to absolutize
*/
throws URI.MalformedURIException {
}
/**
* Expands a system id and returns the system id as a URI, if
* it can be expanded. A return value of null means that the
* identifier is already expanded. An exception thrown
* indicates a failure to expand the id.
*
* @param systemId The systemId to be expanded.
*
* @return Returns the URI string representing the expanded system
* identifier. A null value indicates that the given
* system identifier is already expanded.
*
*/
// check for bad parameters id
return systemId;
}
// if id already expanded, return
try {
return systemId;
}
} catch (URI.MalformedURIException e) {
// continue on...
}
// normalize id
// normalize base
try {
} else {
try {
} catch (URI.MalformedURIException e) {
// for xml schemas we might have baseURI with
// a specified drive
} else {
}
}
}
// expand id
} catch (Exception e) {
// let it go through
}
return systemId;
}
} // expandSystemId(String,String):String
/**
* Expands a system id and returns the system id as a URI, if
* it can be expanded. A return value of null means that the
* identifier is already expanded. An exception thrown
* indicates a failure to expand the id.
*
* @param systemId The systemId to be expanded.
*
* @return Returns the URI string representing the expanded system
* identifier. A null value indicates that the given
* system identifier is already expanded.
*
*/
boolean strict)
throws URI.MalformedURIException {
// check if there is a system id before
// trying to expand it.
return null;
}
// system id has to be a valid URI
if (strict) {
// check if there is a system id before
// trying to expand it.
return null;
}
try {
// if it's already an absolute one, return it
return systemId;
}
}
// if there isn't a base uri, use the working directory
}
// otherwise, use the base uri
else {
try {
}
catch (URI.MalformedURIException e) {
// assume "base" is also a relative uri
}
}
// absolutize the system id using the base
// return the string rep of the new uri (an absolute one)
// if any exception is thrown, it'll get thrown to the caller.
}
// Assume the URIs are well-formed. If it turns out they're not, try fixing them up.
try {
}
catch (URI.MalformedURIException e) {
/** Xerces URI rejects unicode, try java.net.URI
* this is not ideal solution, but it covers known cases which either
* Xerces URI or java.net.URI can handle alone
* will file bug against java.net.URI
*/
try {
} catch (URISyntaxException ex) {
// continue on...
}
}
// check for bad parameters id
return systemId;
}
// normalize id
// normalize base
try {
base = getUserDir();
}
else {
try {
}
catch (URI.MalformedURIException e) {
// for xml schemas we might have baseURI with
// a specified drive
}
else {
}
}
}
// expand id
}
catch (Exception e) {
// let it go through
}
return systemId;
}
} // expandSystemId(String,String,boolean):String
/**
* Helper method for expandSystemId(String,String,boolean):String
*/
throws URI.MalformedURIException {
// If it's already an absolute one, return it
if (systemURI.isAbsoluteURI()) {
return systemId;
}
// If there isn't a base URI, use the working directory
baseURI = getUserDir();
}
else {
if (!baseURI.isAbsoluteURI()) {
// assume "base" is also a relative uri
}
}
// absolutize the system identifier using the base URI
// return the string rep of the new uri (an absolute one)
// if any exception is thrown, it'll get thrown to the caller.
} // expandSystemIdStrictOn(String,String):String
/**
* Attempt to set whether redirects will be followed for an <code>HttpURLConnection</code>.
* This may fail on earlier JDKs which do not support setting this preference.
*/
try {
Method method = HttpURLConnection.class.getMethod("setInstanceFollowRedirects", new Class[] {Boolean.TYPE});
}
// setInstanceFollowRedirects doesn't exist.
}
/**
* Helper method for expandSystemId(String,String,boolean):String
*/
throws URI.MalformedURIException {
// If it's already an absolute one, return it
if (systemURI.isAbsoluteURI()) {
return systemId;
}
/**
* If the scheme's length is only one character,
* it's likely that this was intended as a file
* path. Fixing this up in expandSystemId to
* maintain backwards compatibility.
*/
throw new URI.MalformedURIException();
}
// If there isn't a base URI, use the working directory
baseURI = getUserDir();
}
else {
if (!baseURI.isAbsoluteURI()) {
// assume "base" is also a relative uri
}
}
// absolutize the system identifier using the base URI
// return the string rep of the new uri (an absolute one)
// if any exception is thrown, it'll get thrown to the caller.
} // expandSystemIdStrictOff(String,String):String
// If it's already an absolute one, return it
if (systemURI.isAbsolute()) {
return systemId;
}
/**
* If the scheme's length is only one character,
* it's likely that this was intended as a file
* path. Fixing this up in expandSystemId to
* maintain backwards compatibility.
*/
}
// If there isn't a base URI, use the working directory
baseURI = getUserDir();
}
else {
if (!baseURI.isAbsoluteURI()) {
// assume "base" is also a relative uri
}
}
// absolutize the system identifier using the base URI
// systemURI.absolutize(baseURI);
// return the string rep of the new uri (an absolute one)
// if any exception is thrown, it'll get thrown to the caller.
} // expandSystemIdStrictOff(String,String):String
//
// Protected methods
//
/**
* Returns the IANA encoding name that is auto-detected from
* the bytes specified, with the endian-ness of that encoding where appropriate.
*
* @param b4 The first four bytes of the input.
* @param count The number of bytes actually read.
* @return a 2-element array: the first element, an IANA-encoding string,
* the second element a Boolean which is true iff the document is big endian, false
* if it's little-endian, and null if the distinction isn't relevant.
*/
if (count < 2) {
return defaultEncoding;
}
// UTF-16, with BOM
// UTF-16, big-endian
}
// UTF-16, little-endian
}
// default to UTF-8 if we don't have enough bytes to make a
// good determination of the encoding
if (count < 3) {
return defaultEncoding;
}
// UTF-8 with a BOM
return defaultEncoding;
}
// default to UTF-8 if we don't have enough bytes to make a
// good determination of the encoding
if (count < 4) {
return defaultEncoding;
}
// other encodings
// UCS-4, big endian (1234)
}
// UCS-4, little endian (4321)
}
// UCS-4, unusual octet order (2143)
// REVISIT: What should this be?
}
// UCS-4, unusual octect order (3412)
// REVISIT: What should this be?
}
// UTF-16, big-endian, no BOM
// (or could turn out to be UCS-2...
// REVISIT: What should this be?
}
// UTF-16, little-endian, no BOM
// (or could turn out to be UCS-2...
}
// EBCDIC
// a la xerces1, return CP037 instead of EBCDIC here
}
return defaultEncoding;
} // getEncodingName(byte[],int):Object[]
/**
* Creates a reader capable of reading the given input stream in
* the specified encoding.
*
* @param inputStream The input stream.
* @param encoding The encoding name that the input stream is
* encoded using. If the user has specified that
* Java encoding names are allowed, then the
* encoding name may be a Java encoding name;
* otherwise, it is an ianaEncoding name.
* @param isBigEndian For encodings (like uCS-4), whose names cannot
* specify a byte order, this tells whether the order is bigEndian. null menas
* unknown or not relevant.
*
* @return Returns a reader.
*/
throws IOException {
// normalize encoding name
encoding = "UTF-8";
}
// try to use an optimized reader
if (DEBUG_ENCODINGS) {
}
return new UTF8Reader(inputStream, fBufferSize, fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN), fErrorReporter.getLocale() );
}
if (DEBUG_ENCODINGS) {
}
return new ASCIIReader(inputStream, fBufferSize, fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN), fErrorReporter.getLocale());
}
if(isBigEndian != null) {
if(isBE) {
} else {
}
} else {
"EncodingByteOrderUnsupported",
}
}
if(isBE) {
} else {
}
} else {
"EncodingByteOrderUnsupported",
}
}
// check for valid name
"EncodingDeclInvalid",
// NOTE: AndyH suggested that, on failure, we use ISO Latin 1
// because every byte is a valid ISO Latin 1 character.
// It may not translate correctly but if we failed on
// the encoding anyway, then we're expecting the content
// of the document to be bad. This will just prevent an
// invalid UTF-8 sequence to be detected. This is only
// important when continue-after-fatal-error is turned
// on. -Ac
encoding = "ISO-8859-1";
}
// try to use a Java reader
if (javaEncoding == null) {
if(fAllowJavaEncodings) {
} else {
"EncodingDeclInvalid",
// see comment above.
javaEncoding = "ISO8859_1";
}
}
if (DEBUG_ENCODINGS) {
if (javaEncoding == encoding) {
}
}
} // createReader(InputStream,String, Boolean): Reader
/**
* Return the public identifier for the current document event.
* <p>
* The return value is the public identifier of the document
* entity or of the external parsed entity in which the markup
* triggering the event appears.
*
* @return A string containing the public identifier, or
* null if none is available.
*/
return (fCurrentEntity != null && fCurrentEntity.entityLocation != null) ? fCurrentEntity.entityLocation.getPublicId() : null;
} // getPublicId():String
/**
* Return the expanded system identifier for the current document event.
* <p>
* The return value is the expanded system identifier of the document
* entity or of the external parsed entity in which the markup
* triggering the event appears.
* <p>
* If the system identifier is a URL, the parser must resolve it
* fully before passing it to the application.
*
* @return A string containing the expanded system identifier, or null
* if none is available.
*/
if (fCurrentEntity != null) {
} else {
// search for the first external entity on the stack
}
}
}
}
return null;
} // getExpandedSystemId():String
/**
* Return the literal system identifier for the current document event.
* <p>
* The return value is the literal system identifier of the document
* entity or of the external parsed entity in which the markup
* triggering the event appears.
* <p>
* @return A string containing the literal system identifier, or null
* if none is available.
*/
if (fCurrentEntity != null) {
} else {
// search for the first external entity on the stack
}
}
}
}
return null;
} // getLiteralSystemId():String
/**
* Return the line number where the current document event ends.
* <p>
* <strong>Warning:</strong> The return value from the method
* is intended only as an approximation for the sake of error
* reporting; it is not intended to provide sufficient information
* to edit the character content of the original XML document.
* <p>
* The return value is an approximation of the line number
* in the document entity or external parsed entity where the
* markup triggering the event appears.
* <p>
* If possible, the SAX driver should provide the line position
* of the first character after the text associated with the document
* event. The first line in the document is line 1.
*
* @return The line number, or -1 if none is available.
*/
public int getLineNumber() {
if (fCurrentEntity != null) {
if (fCurrentEntity.isExternal()) {
return fCurrentEntity.lineNumber;
} else {
// search for the first external entity on the stack
if (firstExternalEntity.isExternal()) {
return firstExternalEntity.lineNumber;
}
}
}
}
return -1;
} // getLineNumber():int
/**
* Return the column number where the current document event ends.
* <p>
* <strong>Warning:</strong> The return value from the method
* is intended only as an approximation for the sake of error
* reporting; it is not intended to provide sufficient information
* to edit the character content of the original XML document.
* <p>
* The return value is an approximation of the column number
* in the document entity or external parsed entity where the
* markup triggering the event appears.
* <p>
* If possible, the SAX driver should provide the line position
* of the first character after the text associated with the document
* event.
* <p>
* If possible, the SAX driver should provide the line position
* of the first character after the text associated with the document
* event. The first column in each line is column 1.
*
* @return The column number, or -1 if none is available.
*/
public int getColumnNumber() {
if (fCurrentEntity != null) {
if (fCurrentEntity.isExternal()) {
return fCurrentEntity.columnNumber;
} else {
// search for the first external entity on the stack
if (firstExternalEntity.isExternal()) {
return firstExternalEntity.columnNumber;
}
}
}
}
return -1;
} // getColumnNumber():int
//
// Protected static methods
//
/**
* Fixes a platform dependent filename to standard URI form.
*
* @param str The string to fix.
*
* @return Returns the fixed URI string.
*/
// handle platform dependent strings
// Windows fix
// change "C:blah" to "/C:blah"
if (ch1 == ':') {
}
}
// change "//blah" to "file://blah"
}
}
// replace spaces in file names with %20.
// Original comment from JDK5: the following algorithm might not be
// very performant, but people who want to use invalid URI's have to
// pay the price.
if (pos >= 0) {
// put characters before ' ' into the string builder
for (int i = 0; i < pos; i++)
// and %20 for the space
// for the remamining part, also convert ' ' to "%20".
else
}
}
// done
return str;
} // fixURI(String):String
//
// Package visible methods
//
/** Prints the contents of the buffer. */
final void print() {
if (DEBUG_BUFFER) {
if (fCurrentEntity != null) {
if (i == fCurrentEntity.position) {
}
char c = fCurrentEntity.ch[i];
switch (c) {
case '\n': {
break;
}
case '\r': {
break;
}
case '\t': {
break;
}
case '\\': {
break;
}
default: {
}
}
}
}
}
} else {
}
}
} // print()
/**
* Buffer used in entity manager to reuse character arrays instead
* of creating new ones every time.
*
* @xerces.internal
*
* @author Ankit Pasricha, IBM
*/
private static class CharacterBuffer {
/** character buffer */
private char[] ch;
/** whether the buffer is for an external or internal scanned entity */
private boolean isExternal;
this.isExternal = isExternal;
}
}
/**
* Stores a number of character buffers and provides it to the entity
* manager to use when an entity is seen.
*
* @xerces.internal
*
* @author Ankit Pasricha, IBM
*/
private static class CharacterBufferPool {
private int fExternalBufferSize;
private int fInternalBufferSize;
private int poolSize;
private int fInternalTop;
private int fExternalTop;
}
init();
}
/** Initializes buffer pool. **/
private void init() {
fInternalTop = -1;
fExternalTop = -1;
}
/** Retrieves buffer from pool. **/
if (external) {
if (fExternalTop > -1) {
}
else {
return new CharacterBuffer(true, fExternalBufferSize);
}
}
else {
if (fInternalTop > -1) {
}
else {
return new CharacterBuffer(false, fInternalBufferSize);
}
}
}
/** Returns buffer to pool. **/
if (buffer.isExternal) {
}
}
}
}
/** Sets the size of external buffers and dumps the old pool. **/
fExternalTop = -1;
}
}
/**
* This class wraps the byte inputstreams we're presented with.
* We need it because java.io.InputStreams don't provide
* functionality to reread processed bytes, and they have a habit
* of reading more than one character when you call their read()
* methods. This means that, once we discover the true (declared)
* encoding of a document, we can neither backtrack to read the
* whole doc again nor start reading where we are with a new
* reader.
*
* This class allows rewinding an inputStream by allowing a mark
* to be set, and the stream reset to that position. <strong>The
* class assumes that it needs to read one character per
* invocation when it's read() method is inovked, but uses the
* underlying InputStream's read(char[], offset length) method--it
* won't buffer data read this way!</strong>
*
* @xerces.internal
*
* @author Neil Graham, IBM
* @author Glenn Marcy, IBM
*/
private byte[] fData;
private int fStartOffset;
private int fEndOffset;
private int fOffset;
private int fLength;
private int fMark;
fData = new byte[DEFAULT_XMLDECL_BUFFER_SIZE];
fInputStream = is;
fStartOffset = 0;
fEndOffset = -1;
fOffset = 0;
fLength = 0;
fMark = 0;
}
}
public void rewind() {
}
int b = 0;
}
if (fOffset == fEndOffset) {
return -1;
}
}
b = fInputStream.read();
if (b == -1) {
return -1;
}
fOffset++;
return b & 0xff;
}
if (bytesLeft == 0) {
if (fOffset == fEndOffset) {
return -1;
}
/**
* //System.out.println("fCurrentEntitty = " + fCurrentEntity );
* //System.out.println("fInputStream = " + fInputStream );
* // better get some more for the voracious reader... */
{
fCurrentEntity.xmlDeclChunkRead = true;
}
}
int returnedVal = read();
if(returnedVal == -1) {
return -1;
}
b[off] = (byte)returnedVal;
return 1;
}
if (len <= 0) {
return 0;
}
} else {
}
if (b != null) {
}
return len;
}
public long skip(long n)
throws IOException {
int bytesLeft;
if (n <= 0) {
return 0;
}
if (bytesLeft == 0) {
if (fOffset == fEndOffset) {
return 0;
}
return fInputStream.skip(n);
}
if (n <= bytesLeft) {
fOffset += n;
return n;
}
if (fOffset == fEndOffset) {
return bytesLeft;
}
n -= bytesLeft;
/*
* In a manner of speaking, when this class isn't permitting more
* than one byte at a time to be read, it is "blocking". The
* available() method should indicate how much can be read without
* blocking, so while we're in this mode, it should only indicate
* that bytes in its buffer are available; otherwise, the result of
* available() on the underlying InputStream is appropriate.
*/
}
if (bytesLeft == 0) {
if (fOffset == fEndOffset) {
return -1;
}
: 0;
}
return bytesLeft;
}
}
public void reset() {
//test();
}
public boolean markSupported() {
return true;
}
if (fInputStream != null) {
fInputStream = null;
}
}
} // end of RewindableInputStream class
public void test(){
//System.out.println("TESTING: Added familytree to entityManager");
//Usecase1
//Usecase2
}
} // class XMLEntityManager