- /*
- * Copyright 2001-2004 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.
- */
- /*
- * $Id: SAXImpl.java,v 1.19 2004/02/24 04:21:50 zongaro Exp $
- */
-
- package com.sun.org.apache.xalan.internal.xsltc.dom;
-
- import java.net.URL;
- import java.net.MalformedURLException;
- import java.util.Enumeration;
-
- import javax.xml.transform.Source;
- import javax.xml.transform.dom.DOMSource;
-
- import com.sun.org.apache.xalan.internal.xsltc.DOM;
- import com.sun.org.apache.xalan.internal.xsltc.DOMEnhancedForDTM;
- import com.sun.org.apache.xalan.internal.xsltc.StripFilter;
- import com.sun.org.apache.xalan.internal.xsltc.TransletException;
- import com.sun.org.apache.xalan.internal.xsltc.runtime.BasisLibrary;
- import com.sun.org.apache.xalan.internal.xsltc.runtime.Hashtable;
- import com.sun.org.apache.xml.internal.dtm.DTM;
- import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
- import com.sun.org.apache.xml.internal.dtm.DTMManager;
- import com.sun.org.apache.xml.internal.dtm.DTMWSFilter;
- import com.sun.org.apache.xml.internal.dtm.ref.DTMAxisIterNodeList;
- import com.sun.org.apache.xml.internal.dtm.ref.DTMDefaultBase;
- import com.sun.org.apache.xml.internal.dtm.ref.EmptyIterator;
- import com.sun.org.apache.xml.internal.dtm.ref.DTMNodeProxy;
- import com.sun.org.apache.xml.internal.dtm.ref.sax2dtm.SAX2DTM2;
- import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
- import com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler;
- import com.sun.org.apache.xml.internal.utils.XMLStringFactory;
- import com.sun.org.apache.xml.internal.utils.SystemIDResolver;
- import org.w3c.dom.Node;
- import org.w3c.dom.NodeList;
- import org.w3c.dom.Document;
- import org.w3c.dom.DocumentType;
- import org.w3c.dom.NamedNodeMap;
- import org.w3c.dom.Entity;
-
- import org.xml.sax.Attributes;
- import org.xml.sax.SAXException;
-
-
- /**
- * SAXImpl is the core model for SAX input source. SAXImpl objects are
- * usually created from an XSLTCDTMManager.
- *
- * <p>DOMSource inputs are handled using DOM2SAX + SAXImpl. SAXImpl has a
- * few specific fields (e.g. _node2Ids, _document) to keep DOM-related
- * information. They are used when the processing behavior between DOM and
- * SAX has to be different. Examples of these include id function and
- * unparsed entity.
- *
- * <p>SAXImpl extends SAX2DTM2 instead of SAX2DTM for better performance.
- * @author Jacek Ambroziak
- * @author Santiago Pericas-Geertsen
- * @author Morten Jorgensen
- * @author Douglas Sellers <douglasjsellers@hotmail.com>
- */
- public final class SAXImpl extends SAX2DTM2
- implements DOMEnhancedForDTM, DOMBuilder
- {
-
- /* ------------------------------------------------------------------- */
- /* DOMBuilder fields BEGIN */
- /* ------------------------------------------------------------------- */
-
- // Namespace prefix-to-uri mapping stuff
- private int _uriCount = 0;
- private int _prefixCount = 0;
-
- // Stack used to keep track of what whitespace text nodes are protected
- // by xml:space="preserve" attributes and which nodes that are not.
- private int[] _xmlSpaceStack;
- private int _idx = 1;
- private boolean _preserve = false;
-
- private static final String XML_STRING = "xml:";
- private static final String XML_PREFIX = "xml";
- private static final String XMLSPACE_STRING = "xml:space";
- private static final String PRESERVE_STRING = "preserve";
- private static final String XMLNS_PREFIX = "xmlns";
- private static final String XML_URI = "http://www.w3.org/XML/1998/namespace";
-
- private boolean _escaping = true;
- private boolean _disableEscaping = false;
- private int _textNodeToProcess = DTM.NULL;
-
- /* ------------------------------------------------------------------- */
- /* DOMBuilder fields END */
- /* ------------------------------------------------------------------- */
-
- // empty String for null attribute values
- private final static String EMPTYSTRING = "";
-
- // empty iterator to be returned when there are no children
- private final static DTMAxisIterator EMPTYITERATOR = EmptyIterator.getInstance();
- // The number of expanded names
- private int _namesSize = -1;
-
- // Namespace related stuff
- private Hashtable _nsIndex = new Hashtable();
-
- // The initial size of the text buffer
- private int _size = 0;
-
- // Tracks which textnodes are not escaped
- private BitArray _dontEscape = null;
-
- // The URI to this document
- private String _documentURI = null;
- static private int _documentURIIndex = 0;
-
- // The owner Document when the input source is DOMSource.
- private Document _document;
-
- // The hashtable for org.w3c.dom.Node to node id mapping.
- // This is only used when the input is a DOMSource and the
- // buildIdIndex flag is true.
- private Hashtable _node2Ids = null;
-
- // True if the input source is a DOMSource.
- private boolean _hasDOMSource = false;
-
- // The DTMManager
- private XSLTCDTMManager _dtmManager;
-
- // Support for access/navigation through org.w3c.dom API
- private Node[] _nodes;
- private NodeList[] _nodeLists;
- private final static String XML_LANG_ATTRIBUTE =
- "http://www.w3.org/XML/1998/namespace:@lang";
-
- /**
- * Define the origin of the document from which the tree was built
- */
- public void setDocumentURI(String uri) {
- if (uri != null) {
- setDocumentBaseURI(SystemIDResolver.getAbsoluteURI(uri));
- }
- }
-
- /**
- * Returns the origin of the document from which the tree was built
- */
- public String getDocumentURI() {
- String baseURI = getDocumentBaseURI();
- return (baseURI != null) ? baseURI : "rtf" + _documentURIIndex++;
- }
-
- public String getDocumentURI(int node) {
- return getDocumentURI();
- }
-
- public void setupMapping(String[] names, String[] urisArray,
- int[] typesArray, String[] namespaces) {
- // This method only has a function in DOM adapters
- }
-
- /**
- * Lookup a namespace URI from a prefix starting at node. This method
- * is used in the execution of xsl:element when the prefix is not known
- * at compile time.
- */
- public String lookupNamespace(int node, String prefix)
- throws TransletException
- {
- int anode, nsnode;
- final AncestorIterator ancestors = new AncestorIterator();
-
- if (isElement(node)) {
- ancestors.includeSelf();
- }
-
- ancestors.setStartNode(node);
- while ((anode = ancestors.next()) != DTM.NULL) {
- final NamespaceIterator namespaces = new NamespaceIterator();
-
- namespaces.setStartNode(anode);
- while ((nsnode = namespaces.next()) != DTM.NULL) {
- if (getLocalName(nsnode).equals(prefix)) {
- return getNodeValue(nsnode);
- }
- }
- }
-
- BasisLibrary.runTimeError(BasisLibrary.NAMESPACE_PREFIX_ERR, prefix);
- return null;
- }
-
- /**
- * Returns 'true' if a specific node is an element (of any type)
- */
- public boolean isElement(final int node) {
- return getNodeType(node) == DTM.ELEMENT_NODE;
- }
-
- /**
- * Returns 'true' if a specific node is an attribute (of any type)
- */
- public boolean isAttribute(final int node) {
- return getNodeType(node) == DTM.ATTRIBUTE_NODE;
- }
-
- /**
- * Returns the number of nodes in the tree (used for indexing)
- */
- public int getSize() {
- return getNumberOfNodes();
- }
-
- /**
- * Part of the DOM interface - no function here.
- */
- public void setFilter(StripFilter filter) {
- }
-
-
- /**
- * Returns true if node1 comes before node2 in document order
- */
- public boolean lessThan(int node1, int node2) {
- if (node1 == DTM.NULL) {
- return false;
- }
-
- if (node2 == DTM.NULL) {
- return true;
- }
-
- return (node1 < node2);
- }
-
- /**
- * Create an org.w3c.dom.Node from a node in the tree
- */
- public Node makeNode(int index) {
- if (_nodes == null) {
- _nodes = new Node[_namesSize];
- }
-
- int nodeID = makeNodeIdentity(index);
- if (nodeID < 0) {
- return null;
- }
- else if (nodeID < _nodes.length) {
- return (_nodes[nodeID] != null) ? _nodes[nodeID]
- : (_nodes[nodeID] = new DTMNodeProxy((DTM)this, index));
- }
- else {
- return new DTMNodeProxy((DTM)this, index);
- }
- }
-
- /**
- * Create an org.w3c.dom.Node from a node in an iterator
- * The iterator most be started before this method is called
- */
- public Node makeNode(DTMAxisIterator iter) {
- return makeNode(iter.next());
- }
-
- /**
- * Create an org.w3c.dom.NodeList from a node in the tree
- */
- public NodeList makeNodeList(int index) {
- if (_nodeLists == null) {
- _nodeLists = new NodeList[_namesSize];
- }
-
- int nodeID = makeNodeIdentity(index);
- if (nodeID < 0) {
- return null;
- }
- else if (nodeID < _nodeLists.length) {
- return (_nodeLists[nodeID] != null) ? _nodeLists[nodeID]
- : (_nodeLists[nodeID] = new DTMAxisIterNodeList(this,
- new SingletonIterator(index)));
- }
- else {
- return new DTMAxisIterNodeList(this, new SingletonIterator(index));
- }
- }
-
- /**
- * Create an org.w3c.dom.NodeList from a node iterator
- * The iterator most be started before this method is called
- */
- public NodeList makeNodeList(DTMAxisIterator iter) {
- return new DTMAxisIterNodeList(this, iter);
- }
-
- /**
- * Iterator that returns the namespace nodes as defined by the XPath data
- * model for a given node, filtered by extended type ID.
- */
- public class TypedNamespaceIterator extends NamespaceIterator {
-
- private String _nsPrefix;
-
- /**
- * Constructor TypedChildrenIterator
- *
- *
- * @param nodeType The extended type ID being requested.
- */
- public TypedNamespaceIterator(int nodeType) {
- super();
- if(m_expandedNameTable != null){
- _nsPrefix = m_expandedNameTable.getLocalName(nodeType);
- }
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next() {
- if ((_nsPrefix == null) ||(_nsPrefix.length() == 0) ){
- return (END);
- }
- int node = END;
- for (node = super.next(); node != END; node = super.next()) {
- if (_nsPrefix.compareTo(getLocalName(node))== 0) {
- return returnNode(node);
- }
- }
- return (END);
- }
- } // end of TypedNamespaceIterator
-
-
-
- /**************************************************************
- * This is a specialised iterator for predicates comparing node or
- * attribute values to variable or parameter values.
- */
- private final class NodeValueIterator extends InternalAxisIteratorBase
- {
-
- private DTMAxisIterator _source;
- private String _value;
- private boolean _op;
- private final boolean _isReverse;
- private int _returnType = RETURN_PARENT;
-
- public NodeValueIterator(DTMAxisIterator source, int returnType,
- String value, boolean op)
- {
- _source = source;
- _returnType = returnType;
- _value = value;
- _op = op;
- _isReverse = source.isReverse();
- }
-
- public boolean isReverse()
- {
- return _isReverse;
- }
-
- public DTMAxisIterator cloneIterator()
- {
- try {
- NodeValueIterator clone = (NodeValueIterator)super.clone();
- clone._isRestartable = false;
- clone._source = _source.cloneIterator();
- clone._value = _value;
- clone._op = _op;
- return clone.reset();
- }
- catch (CloneNotSupportedException e) {
- BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
- e.toString());
- return null;
- }
- }
-
- public void setRestartable(boolean isRestartable)
- {
- _isRestartable = isRestartable;
- _source.setRestartable(isRestartable);
- }
-
- public DTMAxisIterator reset()
- {
- _source.reset();
- return resetPosition();
- }
-
- public int next()
- {
- int node;
- while ((node = _source.next()) != END) {
- String val = getStringValueX(node);
- if (_value.equals(val) == _op) {
- if (_returnType == RETURN_CURRENT) {
- return returnNode(node);
- }
- else {
- return returnNode(getParent(node));
- }
- }
- }
- return END;
- }
-
- public DTMAxisIterator setStartNode(int node)
- {
- if (_isRestartable) {
- _source.setStartNode(_startNode = node);
- return resetPosition();
- }
- return this;
- }
-
- public void setMark()
- {
- _source.setMark();
- }
-
- public void gotoMark()
- {
- _source.gotoMark();
- }
- } // end NodeValueIterator
-
- public DTMAxisIterator getNodeValueIterator(DTMAxisIterator iterator, int type,
- String value, boolean op)
- {
- return(DTMAxisIterator)(new NodeValueIterator(iterator, type, value, op));
- }
-
- /**
- * Encapsulates an iterator in an OrderedIterator to ensure node order
- */
- public DTMAxisIterator orderNodes(DTMAxisIterator source, int node)
- {
- return new DupFilterIterator(source);
- }
-
- /**
- * Returns singleton iterator containg the document root
- * Works for them main document (mark == 0)
- */
- public DTMAxisIterator getIterator()
- {
- return new SingletonIterator(getDocument());
- }
-
- /**
- * Get mapping from DOM namespace types to external namespace types
- */
- public int getNSType(int node)
- {
- String s = getNamespaceURI(node);
- if (s == null) {
- return 0;
- }
- int eType = getIdForNamespace(s);
- return ((Integer)_nsIndex.get(new Integer(eType))).intValue();
- }
-
-
-
- /**
- * Returns the namespace type of a specific node
- */
- public int getNamespaceType(final int node)
- {
- return super.getNamespaceType(node);
- }
-
- /**
- * Sets up a translet-to-dom type mapping table
- */
- private int[] setupMapping(String[] names, String[] uris, int[] types, int nNames) {
- // Padding with number of names, because they
- // may need to be added, i.e for RTFs. See copy03
- final int[] result = new int[m_expandedNameTable.getSize()];
- for (int i = 0; i < nNames; i++) {
- //int type = getGeneralizedType(namesArray[i]);
- int type = m_expandedNameTable.getExpandedTypeID(uris[i], names[i], types[i], false);
- result[type] = type;
- }
- return result;
- }
-
- /**
- * Returns the internal type associated with an expanded QName
- */
- public int getGeneralizedType(final String name) {
- return getGeneralizedType(name, true);
- }
-
- /**
- * Returns the internal type associated with an expanded QName
- */
- public int getGeneralizedType(final String name, boolean searchOnly) {
- String lName, ns = null;
- int index = -1;
- int code;
-
- // Is there a prefix?
- if ((index = name.lastIndexOf(":"))> -1) {
- ns = name.substring(0, index);
- }
-
- // Local part of name is after colon. lastIndexOf returns -1 if
- // there is no colon, so lNameStartIdx will be zero in that case.
- int lNameStartIdx = index+1;
-
- // Distinguish attribute and element names. Attribute has @ before
- // local part of name.
- if (name.charAt(lNameStartIdx) == '@') {
- code = DTM.ATTRIBUTE_NODE;
- lNameStartIdx++;
- }
- else {
- code = DTM.ELEMENT_NODE;
- }
-
- // Extract local name
- lName = (lNameStartIdx == 0) ? name : name.substring(lNameStartIdx);
-
- return m_expandedNameTable.getExpandedTypeID(ns, lName, code, searchOnly);
- }
-
- /**
- * Get mapping from DOM element/attribute types to external types
- */
- public short[] getMapping(String[] names, String[] uris, int[] types)
- {
- // Delegate the work to getMapping2 if the document is not fully built.
- // Some of the processing has to be different in this case.
- if (_namesSize < 0) {
- return getMapping2(names, uris, types);
- }
-
- int i;
- final int namesLength = names.length;
- final int exLength = m_expandedNameTable.getSize();
-
- final short[] result = new short[exLength];
-
- // primitive types map to themselves
- for (i = 0; i < DTM.NTYPES; i++) {
- result[i] = (short)i;
- }
-
- for (i = NTYPES; i < exLength; i++) {
- result[i] = m_expandedNameTable.getType(i);
- }
-
- // actual mapping of caller requested names
- for (i = 0; i < namesLength; i++) {
- int genType = m_expandedNameTable.getExpandedTypeID(uris[i],
- names[i],
- types[i],
- true);
- if (genType >= 0 && genType < exLength) {
- result[genType] = (short)(i + DTM.NTYPES);
- }
- }
-
- return result;
- }
-
- /**
- * Get mapping from external element/attribute types to DOM types
- */
- public int[] getReverseMapping(String[] names, String[] uris, int[] types)
- {
- int i;
- final int[] result = new int[names.length + DTM.NTYPES];
-
- // primitive types map to themselves
- for (i = 0; i < DTM.NTYPES; i++) {
- result[i] = i;
- }
-
- // caller's types map into appropriate dom types
- for (i = 0; i < names.length; i++) {
- int type = m_expandedNameTable.getExpandedTypeID(uris[i], names[i], types[i], true);
- result[i+DTM.NTYPES] = type;
- }
- return(result);
- }
-
- /**
- * Get mapping from DOM element/attribute types to external types.
- * This method is used when the document is not fully built.
- */
- private short[] getMapping2(String[] names, String[] uris, int[] types)
- {
- int i;
- final int namesLength = names.length;
- final int exLength = m_expandedNameTable.getSize();
- int[] generalizedTypes = null;
- if (namesLength > 0) {
- generalizedTypes = new int[namesLength];
- }
-
- int resultLength = exLength;
-
- for (i = 0; i < namesLength; i++) {
- // When the document is not fully built, the searchOnly
- // flag should be set to false. That means we should add
- // the type if it is not already in the expanded name table.
- //generalizedTypes[i] = getGeneralizedType(names[i], false);
- generalizedTypes[i] =
- m_expandedNameTable.getExpandedTypeID(uris[i],
- names[i],
- types[i],
- false);
- if (_namesSize < 0 && generalizedTypes[i] >= resultLength) {
- resultLength = generalizedTypes[i] + 1;
- }
- }
-
- final short[] result = new short[resultLength];
-
- // primitive types map to themselves
- for (i = 0; i < DTM.NTYPES; i++) {
- result[i] = (short)i;
- }
-
- for (i = NTYPES; i < exLength; i++) {
- result[i] = m_expandedNameTable.getType(i);
- }
-
- // actual mapping of caller requested names
- for (i = 0; i < namesLength; i++) {
- int genType = generalizedTypes[i];
- if (genType >= 0 && genType < resultLength) {
- result[genType] = (short)(i + DTM.NTYPES);
- }
- }
-
- return(result);
- }
- /**
- * Get mapping from DOM namespace types to external namespace types
- */
- public short[] getNamespaceMapping(String[] namespaces)
- {
- int i;
- final int nsLength = namespaces.length;
- final int mappingLength = _uriCount;
-
- final short[] result = new short[mappingLength];
-
- // Initialize all entries to -1
- for (i=0; i<mappingLength; i++) {
- result[i] = (short)(-1);
- }
-
- for (i=0; i<nsLength; i++) {
- int eType = getIdForNamespace(namespaces[i]);
- Integer type = (Integer)_nsIndex.get(new Integer(eType));
- if (type != null) {
- result[type.intValue()] = (short)i;
- }
- }
-
- return(result);
- }
-
- /**
- * Get mapping from external namespace types to DOM namespace types
- */
- public short[] getReverseNamespaceMapping(String[] namespaces)
- {
- int i;
- final int length = namespaces.length;
- final short[] result = new short[length];
-
- for (i = 0; i < length; i++) {
- int eType = getIdForNamespace(namespaces[i]);
- Integer type = (Integer)_nsIndex.get(new Integer(eType));
- result[i] = (type == null) ? -1 : type.shortValue();
- }
-
- return result;
- }
-
- /**
- * Construct a SAXImpl object using the default block size.
- */
- public SAXImpl(XSLTCDTMManager mgr, Source source,
- int dtmIdentity, DTMWSFilter whiteSpaceFilter,
- XMLStringFactory xstringfactory,
- boolean doIndexing, boolean buildIdIndex)
- {
- this(mgr, source, dtmIdentity, whiteSpaceFilter, xstringfactory,
- doIndexing, DEFAULT_BLOCKSIZE, buildIdIndex, false);
- }
-
- /**
- * Construct a SAXImpl object using the given block size.
- */
- public SAXImpl(XSLTCDTMManager mgr, Source source,
- int dtmIdentity, DTMWSFilter whiteSpaceFilter,
- XMLStringFactory xstringfactory,
- boolean doIndexing, int blocksize,
- boolean buildIdIndex,
- boolean newNameTable)
- {
- super(mgr, source, dtmIdentity, whiteSpaceFilter, xstringfactory,
- doIndexing, blocksize, false, buildIdIndex, newNameTable);
-
- _dtmManager = mgr;
- _size = blocksize;
-
- // Use a smaller size for the space stack if the blocksize is small
- _xmlSpaceStack = new int[blocksize <= 64 ? 4 : 64];
-
- /* From DOMBuilder */
- _xmlSpaceStack[0] = DTMDefaultBase.ROOTNODE;
-
- // If the input source is DOMSource, set the _document field and
- // create the node2Ids table.
- if (source instanceof DOMSource) {
- _hasDOMSource = true;
- DOMSource domsrc = (DOMSource)source;
- Node node = domsrc.getNode();
- if (node instanceof Document) {
- _document = (Document)node;
- }
- else {
- _document = node.getOwnerDocument();
- }
- _node2Ids = new Hashtable();
- }
- }
-
- /**
- * Migrate a DTM built with an old DTMManager to a new DTMManager.
- * After the migration, the new DTMManager will treat the DTM as
- * one that is built by itself.
- * This is used to support DTM sharing between multiple transformations.
- * @param manager the DTMManager
- */
- public void migrateTo(DTMManager manager) {
- super.migrateTo(manager);
- if (manager instanceof XSLTCDTMManager) {
- _dtmManager = (XSLTCDTMManager)manager;
- }
- }
-
- /**
- * Return the node identity for a given id String
- *
- * @param idString The id String
- * @return The identity of the node whose id is the given String.
- */
- public int getElementById(String idString)
- {
- Node node = _document.getElementById(idString);
- if (node != null) {
- Integer id = (Integer)_node2Ids.get(node);
- return (id != null) ? id.intValue() : DTM.NULL;
- }
- else {
- return DTM.NULL;
- }
- }
-
- /**
- * Return true if the input source is DOMSource.
- */
- public boolean hasDOMSource()
- {
- return _hasDOMSource;
- }
-
- /*---------------------------------------------------------------------------*/
- /* DOMBuilder methods begin */
- /*---------------------------------------------------------------------------*/
-
- /**
- * Call this when an xml:space attribute is encountered to
- * define the whitespace strip/preserve settings.
- */
- private void xmlSpaceDefine(String val, final int node)
- {
- final boolean setting = val.equals(PRESERVE_STRING);
- if (setting != _preserve) {
- _xmlSpaceStack[_idx++] = node;
- _preserve = setting;
- }
- }
-
- /**
- * Call this from endElement() to revert strip/preserve setting
- * to whatever it was before the corresponding startElement().
- */
- private void xmlSpaceRevert(final int node)
- {
- if (node == _xmlSpaceStack[_idx - 1]) {
- _idx--;
- _preserve = !_preserve;
- }
- }
-
- /**
- * Find out whether or not to strip whitespace nodes.
- *
- *
- * @return whether or not to strip whitespace nodes.
- */
- protected boolean getShouldStripWhitespace()
- {
- return _preserve ? false : super.getShouldStripWhitespace();
- }
-
- /**
- * Creates a text-node and checks if it is a whitespace node.
- */
- private void handleTextEscaping() {
- if (_disableEscaping && _textNodeToProcess != DTM.NULL
- && _type(_textNodeToProcess) == DTM.TEXT_NODE) {
- if (_dontEscape == null) {
- _dontEscape = new BitArray(_size);
- }
-
- // Resize the _dontEscape BitArray if necessary.
- if (_textNodeToProcess >= _dontEscape.size()) {
- _dontEscape.resize(_dontEscape.size() * 2);
- }
-
- _dontEscape.setBit(_textNodeToProcess);
- _disableEscaping = false;
- }
- _textNodeToProcess = DTM.NULL;
- }
-
-
- /****************************************************************/
- /* SAX Interface Starts Here */
- /****************************************************************/
-
- /**
- * SAX2: Receive notification of character data.
- */
- public void characters(char[] ch, int start, int length) throws SAXException
- {
- super.characters(ch, start, length);
-
- _disableEscaping = !_escaping;
- _textNodeToProcess = getNumberOfNodes();
- }
-
- /**
- * SAX2: Receive notification of the beginning of a document.
- */
- public void startDocument() throws SAXException
- {
- super.startDocument();
-
- _nsIndex.put(new Integer(0), new Integer(_uriCount++));
- definePrefixAndUri(XML_PREFIX, XML_URI);
- }
-
- /**
- * SAX2: Receive notification of the end of a document.
- */
- public void endDocument() throws SAXException
- {
- super.endDocument();
-
- handleTextEscaping();
- _namesSize = m_expandedNameTable.getSize();
- }
-
- /**
- * Specialized interface used by DOM2SAX. This one has an extra Node
- * parameter to build the Node -> id map.
- */
- public void startElement(String uri, String localName,
- String qname, Attributes attributes,
- Node node)
- throws SAXException
- {
- this.startElement(uri, localName, qname, attributes);
-
- if (m_buildIdIndex) {
- _node2Ids.put(node, new Integer(m_parents.peek()));
- }
- }
-
- /**
- * SAX2: Receive notification of the beginning of an element.
- */
- public void startElement(String uri, String localName,
- String qname, Attributes attributes)
- throws SAXException
- {
- super.startElement(uri, localName, qname, attributes);
-
- handleTextEscaping();
-
- if (m_wsfilter != null) {
- // Look for any xml:space attributes
- // Depending on the implementation of attributes, this
- // might be faster than looping through all attributes. ILENE
- final int index = attributes.getIndex(XMLSPACE_STRING);
- if (index >= 0) {
- xmlSpaceDefine(attributes.getValue(index), m_parents.peek());
- }
- }
- }
-
- /**
- * SAX2: Receive notification of the end of an element.
- */
- public void endElement(String namespaceURI, String localName, String qname)
- throws SAXException
- {
- super.endElement(namespaceURI, localName, qname);
-
- handleTextEscaping();
-
- // Revert to strip/preserve-space setting from before this element
- if (m_wsfilter != null) {
- xmlSpaceRevert(m_previous);
- }
- }
-
- /**
- * SAX2: Receive notification of a processing instruction.
- */
- public void processingInstruction(String target, String data)
- throws SAXException
- {
- super.processingInstruction(target, data);
- handleTextEscaping();
- }
-
- /**
- * SAX2: Receive notification of ignorable whitespace in element
- * content. Similar to characters(char[], int, int).
- */
- public void ignorableWhitespace(char[] ch, int start, int length)
- throws SAXException
- {
- super.ignorableWhitespace(ch, start, length);
- _textNodeToProcess = getNumberOfNodes();
- }
-
- /**
- * SAX2: Begin the scope of a prefix-URI Namespace mapping.
- */
- public void startPrefixMapping(String prefix, String uri)
- throws SAXException
- {
- super.startPrefixMapping(prefix, uri);
- handleTextEscaping();
-
- definePrefixAndUri(prefix, uri);
- }
-
- private void definePrefixAndUri(String prefix, String uri)
- throws SAXException
- {
- // Check if the URI already exists before pushing on stack
- Integer eType = new Integer(getIdForNamespace(uri));
- if ((Integer)_nsIndex.get(eType) == null) {
- _nsIndex.put(eType, new Integer(_uriCount++));
- }
- }
-
- /**
- * SAX2: Report an XML comment anywhere in the document.
- */
- public void comment(char[] ch, int start, int length)
- throws SAXException
- {
- super.comment(ch, start, length);
- handleTextEscaping();
- }
-
- public boolean setEscaping(boolean value) {
- final boolean temp = _escaping;
- _escaping = value;
- return temp;
- }
-
- /*---------------------------------------------------------------------------*/
- /* DOMBuilder methods end */
- /*---------------------------------------------------------------------------*/
-
- /**
- * Prints the whole tree to standard output
- */
- public void print(int node, int level)
- {
- switch(getNodeType(node))
- {
- case DTM.ROOT_NODE:
- case DTM.DOCUMENT_NODE:
- print(getFirstChild(node), level);
- break;
- case DTM.TEXT_NODE:
- case DTM.COMMENT_NODE:
- case DTM.PROCESSING_INSTRUCTION_NODE:
- System.out.print(getStringValueX(node));
- break;
- default:
- final String name = getNodeName(node);
- System.out.print("<" + name);
- for (int a = getFirstAttribute(node); a != DTM.NULL; a = getNextAttribute(a))
- {
- System.out.print("\n" + getNodeName(a) + "=\"" + getStringValueX(a) + "\"");
- }
- System.out.print('>');
- for (int child = getFirstChild(node); child != DTM.NULL;
- child = getNextSibling(child)) {
- print(child, level + 1);
- }
- System.out.println("</" + name + '>');
- break;
- }
- }
-
- /**
- * Returns the name of a node (attribute or element).
- */
- public String getNodeName(final int node)
- {
- // Get the node type and make sure that it is within limits
- int nodeh = node;
- final short type = getNodeType(nodeh);
- switch(type)
- {
- case DTM.ROOT_NODE:
- case DTM.DOCUMENT_NODE:
- case DTM.TEXT_NODE:
- case DTM.COMMENT_NODE:
- return EMPTYSTRING;
- case DTM.NAMESPACE_NODE:
- return this.getLocalName(nodeh);
- default:
- return super.getNodeName(nodeh);
- }
- }
-
- /**
- * Returns the namespace URI to which a node belongs
- */
- public String getNamespaceName(final int node)
- {
- if (node == DTM.NULL) {
- return "";
- }
-
- String s;
- return (s = getNamespaceURI(node)) == null ? EMPTYSTRING : s;
- }
-
-
- /**
- * Returns the attribute node of a given type (if any) for an element
- */
- public int getAttributeNode(final int type, final int element)
- {
- for (int attr = getFirstAttribute(element);
- attr != DTM.NULL;
- attr = getNextAttribute(attr))
- {
- if (getExpandedTypeID(attr) == type) return attr;
- }
- return DTM.NULL;
- }
-
- /**
- * Returns the value of a given attribute type of a given element
- */
- public String getAttributeValue(final int type, final int element)
- {
- final int attr = getAttributeNode(type, element);
- return (attr != DTM.NULL) ? getStringValueX(attr) : EMPTYSTRING;
- }
-
- /**
- * This method is for testing/debugging only
- */
- public String getAttributeValue(final String name, final int element)
- {
- return getAttributeValue(getGeneralizedType(name), element);
- }
-
- /**
- * Returns an iterator with all the children of a given node
- */
- public DTMAxisIterator getChildren(final int node)
- {
- return (new ChildrenIterator()).setStartNode(node);
- }
-
- /**
- * Returns an iterator with all children of a specific type
- * for a given node (element)
- */
- public DTMAxisIterator getTypedChildren(final int type)
- {
- return(new TypedChildrenIterator(type));
- }
-
- /**
- * This is a shortcut to the iterators that implement the
- * supported XPath axes (only namespace::) is not supported.
- * Returns a bare-bones iterator that must be initialized
- * with a start node (using iterator.setStartNode()).
- */
- public DTMAxisIterator getAxisIterator(final int axis)
- {
- switch (axis)
- {
- case Axis.SELF:
- return new SingletonIterator();
- case Axis.CHILD:
- return new ChildrenIterator();
- case Axis.PARENT:
- return new ParentIterator();
- case Axis.ANCESTOR:
- return new AncestorIterator();
- case Axis.ANCESTORORSELF:
- return (new AncestorIterator()).includeSelf();
- case Axis.ATTRIBUTE:
- return new AttributeIterator();
- case Axis.DESCENDANT:
- return new DescendantIterator();
- case Axis.DESCENDANTORSELF:
- return (new DescendantIterator()).includeSelf();
- case Axis.FOLLOWING:
- return new FollowingIterator();
- case Axis.PRECEDING:
- return new PrecedingIterator();
- case Axis.FOLLOWINGSIBLING:
- return new FollowingSiblingIterator();
- case Axis.PRECEDINGSIBLING:
- return new PrecedingSiblingIterator();
- case Axis.NAMESPACE:
- return new NamespaceIterator();
- default:
- BasisLibrary.runTimeError(BasisLibrary.AXIS_SUPPORT_ERR, Axis.names[axis]);
- }
- return null;
- }
-
- /**
- * Similar to getAxisIterator, but this one returns an iterator
- * containing nodes of a typed axis (ex.: child::foo)
- */
- public DTMAxisIterator getTypedAxisIterator(int axis, int type)
- {
- // Most common case handled first
- if (axis == Axis.CHILD) {
- return new TypedChildrenIterator(type);
- }
-
- if (type == NO_TYPE) {
- return(EMPTYITERATOR);
- }
-
- switch (axis)
- {
- case Axis.SELF:
- return new TypedSingletonIterator(type);
- case Axis.CHILD:
- return new TypedChildrenIterator(type);
- case Axis.PARENT:
- return new ParentIterator().setNodeType(type);
- case Axis.ANCESTOR:
- return new TypedAncestorIterator(type);
- case Axis.ANCESTORORSELF:
- return (new TypedAncestorIterator(type)).includeSelf();
- case Axis.ATTRIBUTE:
- return new TypedAttributeIterator(type);
- case Axis.DESCENDANT:
- return new TypedDescendantIterator(type);
- case Axis.DESCENDANTORSELF:
- return (new TypedDescendantIterator(type)).includeSelf();
- case Axis.FOLLOWING:
- return new TypedFollowingIterator(type);
- case Axis.PRECEDING:
- return new TypedPrecedingIterator(type);
- case Axis.FOLLOWINGSIBLING:
- return new TypedFollowingSiblingIterator(type);
- case Axis.PRECEDINGSIBLING:
- return new TypedPrecedingSiblingIterator(type);
- case Axis.NAMESPACE:
- return new TypedNamespaceIterator(type);
- default:
- BasisLibrary.runTimeError(BasisLibrary.TYPED_AXIS_SUPPORT_ERR, Axis.names[axis]);
- }
- return null;
- }
-
- /**
- * Do not think that this returns an iterator for the namespace axis.
- * It returns an iterator with nodes that belong in a certain namespace,
- * such as with <xsl:apply-templates select="blob/foo:*"/>
- * The 'axis' specifies the axis for the base iterator from which the
- * nodes are taken, while 'ns' specifies the namespace URI type.
- */
- public DTMAxisIterator getNamespaceAxisIterator(int axis, int ns)
- {
-
- DTMAxisIterator iterator = null;
-
- if (ns == NO_TYPE) {
- return EMPTYITERATOR;
- }
- else {
- switch (axis) {
- case Axis.CHILD:
- return new NamespaceChildrenIterator(ns);
- case Axis.ATTRIBUTE:
- return new NamespaceAttributeIterator(ns);
- default:
- return new NamespaceWildcardIterator(axis, ns);
- }
- }
- }
-
- /**
- * Iterator that handles node tests that test for a namespace, but have
- * a wild card for the local name of the node, i.e., node tests of the
- * form <axis>::<prefix>:*
- */
- public final class NamespaceWildcardIterator
- extends InternalAxisIteratorBase
- {
- /**
- * The namespace type index.
- */
- protected int m_nsType;
-
- /**
- * A nested typed axis iterator that retrieves nodes of the principal
- * node kind for that axis.
- */
- protected DTMAxisIterator m_baseIterator;
-
- /**
- * Constructor NamespaceWildcard
- *
- * @param axis The axis that this iterator will traverse
- * @param nsType The namespace type index
- */
- public NamespaceWildcardIterator(int axis, int nsType) {
- m_nsType = nsType;
-
- // Create a nested iterator that will select nodes of
- // the principal node kind for the selected axis.
- switch (axis) {
- case Axis.ATTRIBUTE: {
- // For "attribute::p:*", the principal node kind is
- // attribute
- m_baseIterator = getAxisIterator(axis);
- }
- case Axis.NAMESPACE: {
- // This covers "namespace::p:*". It is syntactically
- // correct, though it doesn't make much sense.
- m_baseIterator = getAxisIterator(axis);
- }
- default: {
- // In all other cases, the principal node kind is
- // element
- m_baseIterator = getTypedAxisIterator(axis,
- DTM.ELEMENT_NODE);
- }
- }
- }
-
- /**
- * Set start to END should 'close' the iterator,
- * i.e. subsequent call to next() should return END.
- *
- * @param node Sets the root of the iteration.
- *
- * @return A DTMAxisIterator set to the start of the iteration.
- */
- public DTMAxisIterator setStartNode(int node) {
- if (_isRestartable) {
- _startNode = node;
- m_baseIterator.setStartNode(node);
- resetPosition();
- }
- return this;
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next() {
- int node;
-
- while ((node = m_baseIterator.next()) != END) {
- // Return only nodes that are in the selected namespace
- if (getNSType(node) == m_nsType) {
- return returnNode(node);
- }
- }
-
- return END;
- }
-
- /**
- * Returns a deep copy of this iterator. The cloned iterator is not
- * reset.
- *
- * @return a deep copy of this iterator.
- */
- public DTMAxisIterator cloneIterator() {
- try {
- DTMAxisIterator nestedClone = m_baseIterator.cloneIterator();
- NamespaceWildcardIterator clone =
- (NamespaceWildcardIterator) super.clone();
-
- clone.m_baseIterator = nestedClone;
- clone.m_nsType = m_nsType;
- clone._isRestartable = false;
-
- return clone;
- } catch (CloneNotSupportedException e) {
- BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
- e.toString());
- return null;
- }
- }
-
- /**
- * True if this iterator has a reversed axis.
- *
- * @return <code>true</code> if this iterator is a reversed axis.
- */
- public boolean isReverse() {
- return m_baseIterator.isReverse();
- }
-
- public void setMark() {
- m_baseIterator.setMark();
- }
-
- public void gotoMark() {
- m_baseIterator.gotoMark();
- }
- }
-
- /**
- * Iterator that returns children within a given namespace for a
- * given node. The functionality chould be achieved by putting a
- * filter on top of a basic child iterator, but a specialised
- * iterator is used for efficiency (both speed and size of translet).
- */
- public final class NamespaceChildrenIterator
- extends InternalAxisIteratorBase
- {
-
- /** The extended type ID being requested. */
- private final int _nsType;
-
- /**
- * Constructor NamespaceChildrenIterator
- *
- *
- * @param type The extended type ID being requested.
- */
- public NamespaceChildrenIterator(final int type) {
- _nsType = type;
- }
-
- /**
- * Set start to END should 'close' the iterator,
- * i.e. subsequent call to next() should return END.
- *
- * @param node Sets the root of the iteration.
- *
- * @return A DTMAxisIterator set to the start of the iteration.
- */
- public DTMAxisIterator setStartNode(int node) {
- //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
- if (node == DTMDefaultBase.ROOTNODE) {
- node = getDocument();
- }
-
- if (_isRestartable) {
- _startNode = node;
- _currentNode = (node == DTM.NULL) ? DTM.NULL : NOTPROCESSED;
-
- return resetPosition();
- }
-
- return this;
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next() {
- if (_currentNode != DTM.NULL) {
- for (int node = (NOTPROCESSED == _currentNode)
- ? _firstch(makeNodeIdentity(_startNode))
- : _nextsib(_currentNode);
- node != END;
- node = _nextsib(node)) {
- int nodeHandle = makeNodeHandle(node);
-
- if (getNSType(nodeHandle) == _nsType) {
- _currentNode = node;
-
- return returnNode(nodeHandle);
- }
- }
- }
-
- return END;
- }
- } // end of NamespaceChildrenIterator
-
- /**
- * Iterator that returns attributes within a given namespace for a node.
- */
- public final class NamespaceAttributeIterator
- extends InternalAxisIteratorBase
- {
-
- /** The extended type ID being requested. */
- private final int _nsType;
-
- /**
- * Constructor NamespaceAttributeIterator
- *
- *
- * @param nsType The extended type ID being requested.
- */
- public NamespaceAttributeIterator(int nsType) {
- super();
-
- _nsType = nsType;
- }
-
- /**
- * Set start to END should 'close' the iterator,
- * i.e. subsequent call to next() should return END.
- *
- * @param node Sets the root of the iteration.
- *
- * @return A DTMAxisIterator set to the start of the iteration.
- */
- public DTMAxisIterator setStartNode(int node) {
- //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
- if (node == DTMDefaultBase.ROOTNODE) {
- node = getDocument();
- }
-
- if (_isRestartable) {
- int nsType = _nsType;
-
- _startNode = node;
-
- for (node = getFirstAttribute(node);
- node != END;
- node = getNextAttribute(node)) {
- if (getNSType(node) == nsType) {
- break;
- }
- }
-
- _currentNode = node;
- return resetPosition();
- }
-
- return this;
- }
-
- /**
- * Get the next node in the iteration.
- *
- * @return The next node handle in the iteration, or END.
- */
- public int next() {
- int node = _currentNode;
- int nsType = _nsType;
- int nextNode;
-
- if (node == END) {
- return END;
- }
-
- for (nextNode = getNextAttribute(node);
- nextNode != END;
- nextNode = getNextAttribute(nextNode)) {
- if (getNSType(nextNode) == nsType) {
- break;
- }
- }
-
- _currentNode = nextNode;
-
- return returnNode(node);
- }
- } // end of NamespaceAttributeIterator
-
- /**
- * Returns an iterator with all descendants of a node that are of
- * a given type.
- */
- public DTMAxisIterator getTypedDescendantIterator(int type)
- {
- return new TypedDescendantIterator(type);
- }
-
- /**
- * Returns the nth descendant of a node
- */
- public DTMAxisIterator getNthDescendant(int type, int n, boolean includeself)
- {
- DTMAxisIterator source = (DTMAxisIterator) new TypedDescendantIterator(type);
- return new NthDescendantIterator(n);
- }
-
- /**
- * Copy the string value of a node directly to an output handler
- */
- public void characters(final int node, SerializationHandler handler)
- throws TransletException
- {
- if (node != DTM.NULL) {
- try {
- dispatchCharactersEvents(node, handler, false);
- } catch (SAXException e) {
- throw new TransletException(e);
- }
- }
- }
-
- /**
- * Copy a node-set to an output handler
- */
- public void copy(DTMAxisIterator nodes, SerializationHandler handler)
- throws TransletException
- {
- int node;
- while ((node = nodes.next()) != DTM.NULL) {
- copy(node, handler);
- }
- }
-
- /**
- * Copy the whole tree to an output handler
- */
- public void copy(SerializationHandler handler) throws TransletException
- {
- copy(getDocument(), handler);
- }
-
- /**
- * Performs a deep copy (ref. XSLs copy-of())
- *
- * TODO: Copy namespace declarations. Can't be done until we
- * add namespace nodes and keep track of NS prefixes
- * TODO: Copy comment nodes
- */
- public void copy(final int node, SerializationHandler handler)
- throws TransletException
- {
- copy(node, handler, false );
- }
-
-
- private final void copy(final int node, SerializationHandler handler, boolean isChild)
- throws TransletException
- {
- int nodeID = makeNodeIdentity(node);
- int eType = _exptype2(nodeID);
- int type = _exptype2Type(eType);
-
- try {
- switch(type)
- {
- case DTM.ROOT_NODE:
- case DTM.DOCUMENT_NODE:
- for(int c = _firstch2(nodeID); c != DTM.NULL; c = _nextsib2(c)) {
- copy(makeNodeHandle(c), handler, true);
- }
- break;
- case DTM.PROCESSING_INSTRUCTION_NODE:
- copyPI(node, handler);
- break;
- case DTM.COMMENT_NODE:
- handler.comment(getStringValueX(node));
- break;
- case DTM.TEXT_NODE:
- boolean oldEscapeSetting = false;
- boolean escapeBit = false;
-
- if (_dontEscape != null) {
- escapeBit = _dontEscape.getBit(getNodeIdent(node));
- if (escapeBit) {
- oldEscapeSetting = handler.setEscaping(false);
- }
- }
-
- copyTextNode(nodeID, handler);
-
- if (escapeBit) {
- handler.setEscaping(oldEscapeSetting);
- }
- break;
- case DTM.ATTRIBUTE_NODE:
- copyAttribute(nodeID, eType, handler);
- break;
- case DTM.NAMESPACE_NODE:
- handler.namespaceAfterStartElement(getNodeNameX(node), getNodeValue(node));
- break;
- default:
- if (type == DTM.ELEMENT_NODE)
- {
- // Start element definition
- final String name = copyElement(nodeID, eType, handler);
- //if(isChild) => not to copy any namespaces from parents
- // else copy all namespaces in scope
- copyNS(nodeID, handler,!isChild);
- copyAttributes(nodeID, handler);
- // Copy element children
- for (int c = _firstch2(nodeID); c != DTM.NULL; c = _nextsib2(c)) {
- copy(makeNodeHandle(c), handler, true);
- }
-
- // Close element definition
- handler.endElement(name);
- }
- // Shallow copy of attribute to output handler
- else {
- final String uri = getNamespaceName(node);
- if (uri.length() != 0) {
- final String prefix = getPrefix(node);
- handler.namespaceAfterStartElement(prefix, uri);
- }
- handler.addAttribute(getNodeName(node), getNodeValue(node));
- }
- break;
- }
- }
- catch (Exception e) {
- throw new TransletException(e);
- }
-
- }
- /**
- * Copies a processing instruction node to an output handler
- */
- private void copyPI(final int node, SerializationHandler handler)
- throws TransletException
- {
- final String target = getNodeName(node);
- final String value = getStringValueX(node);
-
- try {
- handler.processingInstruction(target, value);
- } catch (Exception e) {
- throw new TransletException(e);
- }
- }
-
- /**
- * Performs a shallow copy (ref. XSLs copy())
- */
- public String shallowCopy(final int node, SerializationHandler handler)
- throws TransletException
- {
- int nodeID = makeNodeIdentity(node);
- int exptype = _exptype2(nodeID);
- int type = _exptype2Type(exptype);
-
- try {
- switch(type)
- {
- case DTM.ELEMENT_NODE:
- final String name = copyElement(nodeID, exptype, handler);
- copyNS(nodeID, handler, true);
- return name;
- case DTM.ROOT_NODE:
- case DTM.DOCUMENT_NODE:
- return EMPTYSTRING;
- case DTM.TEXT_NODE:
- copyTextNode(nodeID, handler);
- return null;
- case DTM.PROCESSING_INSTRUCTION_NODE:
- copyPI(node, handler);
- return null;
- case DTM.COMMENT_NODE:
- handler.comment(getStringValueX(node));
- return null;
- case DTM.NAMESPACE_NODE:
- handler.namespaceAfterStartElement(getNodeNameX(node), getNodeValue(node));
- return null;
- case DTM.ATTRIBUTE_NODE:
- copyAttribute(nodeID, exptype, handler);
- return null;
- default:
- final String uri1 = getNamespaceName(node);
- if (uri1.length() != 0) {
- final String prefix = getPrefix(node);
- handler.namespaceAfterStartElement(prefix, uri1);
- }
- handler.addAttribute(getNodeName(node), getNodeValue(node));
- return null;
- }
- } catch (Exception e) {
- throw new TransletException(e);
- }
- }
-
- /**
- * Returns a node' defined language for a node (if any)
- */
- public String getLanguage(int node)
- {
- int parent = node;
- while (DTM.NULL != parent) {
- if (DTM.ELEMENT_NODE == getNodeType(parent)) {
- int langAttr = getAttributeNode(parent, "http://www.w3.org/XML/1998/namespace", "lang");
-
- if (DTM.NULL != langAttr) {
- return getNodeValue(langAttr);
- }
- }
-
- parent = getParent(parent);
- }
- return(null);
- }
-
- /**
- * Returns an instance of the DOMBuilder inner class
- * This class will consume the input document through a SAX2
- * interface and populate the tree.
- */
- public DOMBuilder getBuilder()
- {
- return this;
- }
-
- /**
- * Return a SerializationHandler for output handling.
- * This method is used by Result Tree Fragments.
- */
- public SerializationHandler getOutputDomBuilder()
- {
- return new ToXMLSAXHandler(this, "UTF-8");
- }
-
- /**
- * Return a instance of a DOM class to be used as an RTF
- */
- public DOM getResultTreeFrag(int initSize, int rtfType)
- {
- return getResultTreeFrag(initSize, rtfType, true);
- }
-
- /**
- * Return a instance of a DOM class to be used as an RTF
- *
- * @param initSize The initial size of the DOM.
- * @param rtfType The type of the RTF
- * @param addToManager true if the RTF should be registered with the DTMManager.
- * @return The DOM object which represents the RTF.
- */
- public DOM getResultTreeFrag(int initSize, int rtfType, boolean addToManager)
- {
- if (rtfType == DOM.SIMPLE_RTF) {
- if (addToManager) {
- int dtmPos = _dtmManager.getFirstFreeDTMID();
- SimpleResultTreeImpl rtf = new SimpleResultTreeImpl(_dtmManager,
- dtmPos << DTMManager.IDENT_DTM_NODE_BITS);
- _dtmManager.addDTM(rtf, dtmPos, 0);
- return rtf;
- }
- else {
- return new SimpleResultTreeImpl(_dtmManager, 0);
- }
- }
- else if (rtfType == DOM.ADAPTIVE_RTF) {
- if (addToManager) {
- int dtmPos = _dtmManager.getFirstFreeDTMID();
- AdaptiveResultTreeImpl rtf = new AdaptiveResultTreeImpl(_dtmManager,
- dtmPos << DTMManager.IDENT_DTM_NODE_BITS,
- m_wsfilter, initSize, m_buildIdIndex);
- _dtmManager.addDTM(rtf, dtmPos, 0);
- return rtf;
-
- }
- else {
- return new AdaptiveResultTreeImpl(_dtmManager, 0,
- m_wsfilter, initSize, m_buildIdIndex);
- }
- }
- else {
- return (DOM) _dtmManager.getDTM(null, true, m_wsfilter,
- true, false, false,
- initSize, m_buildIdIndex);
- }
- }
-
- /**
- * %HZ% Need Javadoc
- */
- public Hashtable getElementsWithIDs() {
- if (m_idAttributes == null) {
- return null;
- }
-
- // Convert a java.util.Hashtable to an xsltc.runtime.Hashtable
- Enumeration idValues = m_idAttributes.keys();
- if (!idValues.hasMoreElements()) {
- return null;
- }
-
- Hashtable idAttrsTable = new Hashtable();
-
- while (idValues.hasMoreElements()) {
- Object idValue = idValues.nextElement();
-
- idAttrsTable.put(idValue, m_idAttributes.get(idValue));
- }
-
- return idAttrsTable;
- }
-
- /**
- * The getUnparsedEntityURI function returns the URI of the unparsed
- * entity with the specified name in the same document as the context
- * node (see [3.3 Unparsed Entities]). It returns the empty string if
- * there is no such entity.
- */
- public String getUnparsedEntityURI(String name)
- {
- // Special handling for DOM input
- if (_document != null) {
- String uri = "";
- DocumentType doctype = _document.getDoctype();
- if (doctype != null) {
- NamedNodeMap entities = doctype.getEntities();
-
- if (entities == null) {
- return uri;
- }
-
- Entity entity = (Entity) entities.getNamedItem(name);
-
- if (entity == null) {
- return uri;
- }
-
- String notationName = entity.getNotationName();
- if (notationName != null) {
- uri = entity.getSystemId();
- if (uri == null) {
- uri = entity.getPublicId();
- }
- }
- }
- return uri;
- }
- else {
- return super.getUnparsedEntityURI(name);
- }
- }
-
- }