📄 simpleresulttreeimpl.java
字号:
/* * Copyright 1999-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: SimpleResultTreeImpl.java,v 1.2.4.1 2005/09/06 10:09:25 pvedula Exp $ */package com.sun.org.apache.xalan.internal.xsltc.dom;import com.sun.org.apache.xalan.internal.xsltc.DOM;import com.sun.org.apache.xalan.internal.xsltc.TransletException;import com.sun.org.apache.xalan.internal.xsltc.StripFilter;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.Axis;import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;import com.sun.org.apache.xml.internal.dtm.DTMAxisTraverser;import com.sun.org.apache.xml.internal.dtm.DTMManager;import com.sun.org.apache.xml.internal.dtm.ref.DTMAxisIteratorBase;import com.sun.org.apache.xml.internal.dtm.ref.DTMManagerDefault;import com.sun.org.apache.xml.internal.serializer.EmptySerializer;import com.sun.org.apache.xml.internal.serializer.SerializationHandler;import com.sun.org.apache.xml.internal.utils.XMLString;import com.sun.org.apache.xml.internal.utils.XMLStringDefault;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import org.xml.sax.SAXException;import javax.xml.transform.SourceLocator;/** * This class represents a light-weight DOM model for simple result tree fragment(RTF). * A simple RTF is an RTF that has only one Text node. The Text node can be produced by a * combination of Text, xsl:value-of and xsl:number instructions. It can also be produced * by a control structure (xsl:if or xsl:choose) whose body is pure Text. * <p> * A SimpleResultTreeImpl has only two nodes, i.e. the ROOT node and its Text child. All DOM * interfaces are overridden with this in mind. For example, the getStringValue() interface * returns the value of the Text node. This class receives the character data from the * characters() interface. * <p> * This class implements DOM and SerializationHandler. It also implements the DTM interface * for support in MultiDOM. The nested iterators (SimpleIterator and SingletonIterator) are * used to support the nodeset() extension function. */public class SimpleResultTreeImpl extends EmptySerializer implements DOM, DTM{ /** * The SimpleIterator is designed to support the nodeset() extension function. It has * a traversal direction parameter. The DOWN direction is used for child and descendant * axes, while the UP direction is used for parent and ancestor axes. * * This iterator only handles two nodes (RTF_ROOT and RTF_TEXT). If the type is set, * it will also match the node type with the given type. */ public final class SimpleIterator extends DTMAxisIteratorBase { static final int DIRECTION_UP = 0; static final int DIRECTION_DOWN = 1; static final int NO_TYPE = -1; // The direction of traversal (default to DOWN). // DOWN is for child and descendant. UP is for parent and ancestor. int _direction = DIRECTION_DOWN; int _type = NO_TYPE; int _currentNode; public SimpleIterator() { } public SimpleIterator(int direction) { _direction = direction; } public SimpleIterator(int direction, int type) { _direction = direction; _type = type; } public int next() { // Increase the node ID for down traversal. Also match the node type // if the type is given. if (_direction == DIRECTION_DOWN) { while (_currentNode < NUMBER_OF_NODES) { if (_type != NO_TYPE) { if ((_currentNode == RTF_ROOT && _type == DTM.ROOT_NODE) || (_currentNode == RTF_TEXT && _type == DTM.TEXT_NODE)) return returnNode(getNodeHandle(_currentNode++)); else _currentNode++; } else return returnNode(getNodeHandle(_currentNode++)); } return END; } // Decrease the node ID for up traversal. else { while (_currentNode >= 0) { if (_type != NO_TYPE) { if ((_currentNode == RTF_ROOT && _type == DTM.ROOT_NODE) || (_currentNode == RTF_TEXT && _type == DTM.TEXT_NODE)) return returnNode(getNodeHandle(_currentNode--)); else _currentNode--; } else return returnNode(getNodeHandle(_currentNode--)); } return END; } } public DTMAxisIterator setStartNode(int nodeHandle) { int nodeID = getNodeIdent(nodeHandle); _startNode = nodeID; // Increase the node ID by 1 if self is not included. if (!_includeSelf && nodeID != DTM.NULL) { if (_direction == DIRECTION_DOWN) nodeID++; else if (_direction == DIRECTION_UP) nodeID--; } _currentNode = nodeID; return this; } public void setMark() { _markedNode = _currentNode; } public void gotoMark() { _currentNode = _markedNode; } } // END of SimpleIterator /** * The SingletonIterator is used for the self axis. */ public final class SingletonIterator extends DTMAxisIteratorBase { static final int NO_TYPE = -1; int _type = NO_TYPE; int _currentNode; public SingletonIterator() { } public SingletonIterator(int type) { _type = type; } public void setMark() { _markedNode = _currentNode; } public void gotoMark() { _currentNode = _markedNode; } public DTMAxisIterator setStartNode(int nodeHandle) { _currentNode = _startNode = getNodeIdent(nodeHandle); return this; } public int next() { if (_currentNode == END) return END; _currentNode = END; if (_type != NO_TYPE) { if ((_currentNode == RTF_ROOT && _type == DTM.ROOT_NODE) || (_currentNode == RTF_TEXT && _type == DTM.TEXT_NODE)) return getNodeHandle(_currentNode); } else return getNodeHandle(_currentNode); return END; } } // END of SingletonIterator // empty iterator to be returned when there are no children private final static DTMAxisIterator EMPTY_ITERATOR = new DTMAxisIteratorBase() { public DTMAxisIterator reset() { return this; } public DTMAxisIterator setStartNode(int node) { return this; } public int next() { return DTM.NULL; } public void setMark() {} public void gotoMark() {} public int getLast() { return 0; } public int getPosition() { return 0; } public DTMAxisIterator cloneIterator() { return this; } public void setRestartable(boolean isRestartable) { } }; // The root node id of the simple RTF public static final int RTF_ROOT = 0; // The Text node id of the simple RTF (simple RTF has only one Text node). public static final int RTF_TEXT = 1; // The number of nodes. public static final int NUMBER_OF_NODES = 2; // Document URI index, which increases by 1 at each getDocumentURI() call. private static int _documentURIIndex = 0; // Constant for empty String private static final String EMPTY_STR = ""; // The String value of the Text node. // This is set at the endDocument() call. private String _text; // The array of Text items, which is built by the characters() call. // The characters() interface can be called multiple times. Each character item // can have different escape settings. protected String[] _textArray; // The DTMManager protected XSLTCDTMManager _dtmManager; // Number of character items protected int _size = 0; // The document ID private int _documentID; // A BitArray, each bit holding the escape setting for a character item. private BitArray _dontEscape = null; // The current escape setting private boolean _escaping = true; // Create a SimpleResultTreeImpl from a DTMManager and a document ID. public SimpleResultTreeImpl(XSLTCDTMManager dtmManager, int documentID) { _dtmManager = dtmManager; _documentID = documentID; _textArray = new String[4]; } public DTMManagerDefault getDTMManager() { return _dtmManager; } // Return the document ID public int getDocument() { return _documentID; } // Return the String value of the RTF public String getStringValue() { return _text; } public DTMAxisIterator getIterator() { return new SingletonIterator(getDocument()); } public DTMAxisIterator getChildren(final int node) { return new SimpleIterator().setStartNode(node); } public DTMAxisIterator getTypedChildren(final int type) { return new SimpleIterator(SimpleIterator.DIRECTION_DOWN, type); } // Return the axis iterator for a given axis. // The SimpleIterator is used for the child, descendant, parent and ancestor axes. public DTMAxisIterator getAxisIterator(final int axis) { switch (axis) { case Axis.CHILD: case Axis.DESCENDANT: return new SimpleIterator(SimpleIterator.DIRECTION_DOWN); case Axis.PARENT: case Axis.ANCESTOR: return new SimpleIterator(SimpleIterator.DIRECTION_UP); case Axis.ANCESTORORSELF: return (new SimpleIterator(SimpleIterator.DIRECTION_UP)).includeSelf(); case Axis.DESCENDANTORSELF: return (new SimpleIterator(SimpleIterator.DIRECTION_DOWN)).includeSelf(); case Axis.SELF: return new SingletonIterator(); default: return EMPTY_ITERATOR; } } public DTMAxisIterator getTypedAxisIterator(final int axis, final int type) { switch (axis) { case Axis.CHILD: case Axis.DESCENDANT: return new SimpleIterator(SimpleIterator.DIRECTION_DOWN, type); case Axis.PARENT: case Axis.ANCESTOR: return new SimpleIterator(SimpleIterator.DIRECTION_UP, type); case Axis.ANCESTORORSELF: return (new SimpleIterator(SimpleIterator.DIRECTION_UP, type)).includeSelf(); case Axis.DESCENDANTORSELF: return (new SimpleIterator(SimpleIterator.DIRECTION_DOWN, type)).includeSelf(); case Axis.SELF: return new SingletonIterator(type); default: return EMPTY_ITERATOR; } } // %REVISIT% Can this one ever get used? public DTMAxisIterator getNthDescendant(int node, int n, boolean includeself) { return null; } public DTMAxisIterator getNamespaceAxisIterator(final int axis, final int ns) { return null; } // %REVISIT% Can this one ever get used? public DTMAxisIterator getNodeValueIterator(DTMAxisIterator iter, int returnType, String value, boolean op) { return null; } public DTMAxisIterator orderNodes(DTMAxisIterator source, int node) { return source; } public String getNodeName(final int node) { if (getNodeIdent(node) == RTF_TEXT) return "#text"; else return EMPTY_STR; } public String getNodeNameX(final int node) { return EMPTY_STR; } public String getNamespaceName(final int node) { return EMPTY_STR; } // Return the expanded type id of a given node public int getExpandedTypeID(final int nodeHandle) { int nodeID = getNodeIdent(nodeHandle); if (nodeID == RTF_TEXT) return DTM.TEXT_NODE; else if (nodeID == RTF_ROOT) return DTM.ROOT_NODE; else return DTM.NULL; } public int getNamespaceType(final int node) { return 0; } public int getParent(final int nodeHandle) { int nodeID = getNodeIdent(nodeHandle); return (nodeID == RTF_TEXT) ? getNodeHandle(RTF_ROOT) : DTM.NULL; } public int getAttributeNode(final int gType, final int element) { return DTM.NULL; } public String getStringValueX(final int nodeHandle) { int nodeID = getNodeIdent(nodeHandle); if (nodeID == RTF_ROOT || nodeID == RTF_TEXT) return _text; else return EMPTY_STR; } public void copy(final int node, SerializationHandler handler) throws TransletException { characters(node, handler); } public void copy(DTMAxisIterator nodes, SerializationHandler handler) throws TransletException { int node; while ((node = nodes.next()) != DTM.NULL) { copy(node, handler); } } public String shallowCopy(final int node, SerializationHandler handler) throws TransletException { characters(node, handler); return null; } public boolean lessThan(final int node1, final int node2) { if (node1 == DTM.NULL) { return false; } else if (node2 == DTM.NULL) { return true; } else return (node1 < node2); } /** * Dispatch the character content of a node to an output handler. * * The escape setting should be taken care of when outputting to * a handler. */ public void characters(final int node, SerializationHandler handler) throws TransletException { int nodeID = getNodeIdent(node); if (nodeID == RTF_ROOT || nodeID == RTF_TEXT) { boolean escapeBit = false; boolean oldEscapeSetting = false; try { for (int i = 0; i < _size; i++) { if (_dontEscape != null) { escapeBit = _dontEscape.getBit(i); if (escapeBit) { oldEscapeSetting = handler.setEscaping(false); } } handler.characters(_textArray[i]); if (escapeBit) { handler.setEscaping(oldEscapeSetting); } } } catch (SAXException e) { throw new TransletException(e); } } } // %REVISIT% Can the makeNode() and makeNodeList() interfaces ever get used? public Node makeNode(int index) { return null;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -