Source Home >> Java Source 1.6.0 >> com.sun.org.apache.xalan.internal.xsltc.dom.SAXImpl V 0.09
  • 0001/*
  • 0002 * Copyright 2001-2004 The Apache Software Foundation.
  • 0003 *
  • 0004 * Licensed under the Apache License, Version 2.0 (the "License");
  • 0005 * you may not use this file except in compliance with the License.
  • 0006 * You may obtain a copy of the License at
  • 0007 *
  • 0008 * http://www.apache.org/licenses/LICENSE-2.0
  • 0009 *
  • 0010 * Unless required by applicable law or agreed to in writing, software
  • 0011 * distributed under the License is distributed on an "AS IS" BASIS,
  • 0012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  • 0013 * See the License for the specific language governing permissions and
  • 0014 * limitations under the License.
  • 0015 */
  • 0016/*
  • 0017 * $Id: SAXImpl.java,v 1.5 2005/09/28 13:48:37 pvedula Exp $
  • 0018 */
  • 0019
  • 0020package com.sun.org.apache.xalan.internal.xsltc.dom;
  • 0021
  • 0022import java.net.URL;
  • 0023import java.net.MalformedURLException;
  • 0024import java.util.Enumeration;
  • 0025
  • 0026import javax.xml.transform.Source;
  • 0027import javax.xml.transform.dom.DOMSource;
  • 0028
  • 0029import com.sun.org.apache.xalan.internal.xsltc.DOM;
  • 0030import com.sun.org.apache.xalan.internal.xsltc.DOMEnhancedForDTM;
  • 0031import com.sun.org.apache.xalan.internal.xsltc.StripFilter;
  • 0032import com.sun.org.apache.xalan.internal.xsltc.TransletException;
  • 0033import com.sun.org.apache.xalan.internal.xsltc.runtime.BasisLibrary;
  • 0034import com.sun.org.apache.xalan.internal.xsltc.runtime.Hashtable;
  • 0035import com.sun.org.apache.xml.internal.dtm.DTM;
  • 0036import com.sun.org.apache.xml.internal.dtm.Axis;
  • 0037import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
  • 0038import com.sun.org.apache.xml.internal.dtm.DTMManager;
  • 0039import com.sun.org.apache.xml.internal.dtm.DTMWSFilter;
  • 0040import com.sun.org.apache.xml.internal.dtm.ref.DTMAxisIterNodeList;
  • 0041import com.sun.org.apache.xml.internal.dtm.ref.DTMDefaultBase;
  • 0042import com.sun.org.apache.xml.internal.dtm.ref.EmptyIterator;
  • 0043import com.sun.org.apache.xml.internal.dtm.ref.DTMNodeProxy;
  • 0044import com.sun.org.apache.xml.internal.dtm.ref.sax2dtm.SAX2DTM2;
  • 0045import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
  • 0046import com.sun.org.apache.xml.internal.serializer.ToXMLSAXHandler;
  • 0047import com.sun.org.apache.xml.internal.utils.XMLStringFactory;
  • 0048import com.sun.org.apache.xml.internal.utils.SystemIDResolver;
  • 0049import org.w3c.dom.Node;
  • 0050import org.w3c.dom.NodeList;
  • 0051import org.w3c.dom.Document;
  • 0052import org.w3c.dom.DocumentType;
  • 0053import org.w3c.dom.NamedNodeMap;
  • 0054import org.w3c.dom.Entity;
  • 0055
  • 0056import org.xml.sax.Attributes;
  • 0057import org.xml.sax.SAXException;
  • 0058
  • 0059
  • 0060/**
  • 0061 * SAXImpl is the core model for SAX input source. SAXImpl objects are
  • 0062 * usually created from an XSLTCDTMManager.
  • 0063 *
  • 0064 * <p>DOMSource inputs are handled using DOM2SAX + SAXImpl. SAXImpl has a
  • 0065 * few specific fields (e.g. _node2Ids, _document) to keep DOM-related
  • 0066 * information. They are used when the processing behavior between DOM and
  • 0067 * SAX has to be different. Examples of these include id function and
  • 0068 * unparsed entity.
  • 0069 *
  • 0070 * <p>SAXImpl extends SAX2DTM2 instead of SAX2DTM for better performance.
  • 0071 * @author Jacek Ambroziak
  • 0072 * @author Santiago Pericas-Geertsen
  • 0073 * @author Morten Jorgensen
  • 0074 * @author Douglas Sellers <douglasjsellers@hotmail.com>
  • 0075 */
  • 0076public final class SAXImpl extends SAX2DTM2
  • 0077 implements DOMEnhancedForDTM, DOMBuilder
  • 0078{
  • 0079
  • 0080 /* ------------------------------------------------------------------- */
  • 0081 /* DOMBuilder fields BEGIN */
  • 0082 /* ------------------------------------------------------------------- */
  • 0083
  • 0084 // Namespace prefix-to-uri mapping stuff
  • 0085 private int _uriCount = 0;
  • 0086 private int _prefixCount = 0;
  • 0087
  • 0088 // Stack used to keep track of what whitespace text nodes are protected
  • 0089 // by xml:space="preserve" attributes and which nodes that are not.
  • 0090 private int[] _xmlSpaceStack;
  • 0091 private int _idx = 1;
  • 0092 private boolean _preserve = false;
  • 0093
  • 0094 private static final String XML_STRING = "xml:";
  • 0095 private static final String XML_PREFIX = "xml";
  • 0096 private static final String XMLSPACE_STRING = "xml:space";
  • 0097 private static final String PRESERVE_STRING = "preserve";
  • 0098 private static final String XMLNS_PREFIX = "xmlns";
  • 0099 private static final String XML_URI = "http://www.w3.org/XML/1998/namespace";
  • 0100
  • 0101 private boolean _escaping = true;
  • 0102 private boolean _disableEscaping = false;
  • 0103 private int _textNodeToProcess = DTM.NULL;
  • 0104
  • 0105 /* ------------------------------------------------------------------- */
  • 0106 /* DOMBuilder fields END */
  • 0107 /* ------------------------------------------------------------------- */
  • 0108
  • 0109 // empty String for null attribute values
  • 0110 private final static String EMPTYSTRING = "";
  • 0111
  • 0112 // empty iterator to be returned when there are no children
  • 0113 private final static DTMAxisIterator EMPTYITERATOR = EmptyIterator.getInstance();
  • 0114 // The number of expanded names
  • 0115 private int _namesSize = -1;
  • 0116
  • 0117 // Namespace related stuff
  • 0118 private Hashtable _nsIndex = new Hashtable();
  • 0119
  • 0120 // The initial size of the text buffer
  • 0121 private int _size = 0;
  • 0122
  • 0123 // Tracks which textnodes are not escaped
  • 0124 private BitArray _dontEscape = null;
  • 0125
  • 0126 // The URI to this document
  • 0127 private String _documentURI = null;
  • 0128 static private int _documentURIIndex = 0;
  • 0129
  • 0130 // The owner Document when the input source is DOMSource.
  • 0131 private Document _document;
  • 0132
  • 0133 // The hashtable for org.w3c.dom.Node to node id mapping.
  • 0134 // This is only used when the input is a DOMSource and the
  • 0135 // buildIdIndex flag is true.
  • 0136 private Hashtable _node2Ids = null;
  • 0137
  • 0138 // True if the input source is a DOMSource.
  • 0139 private boolean _hasDOMSource = false;
  • 0140
  • 0141 // The DTMManager
  • 0142 private XSLTCDTMManager _dtmManager;
  • 0143
  • 0144 // Support for access/navigation through org.w3c.dom API
  • 0145 private Node[] _nodes;
  • 0146 private NodeList[] _nodeLists;
  • 0147 private final static String XML_LANG_ATTRIBUTE =
  • 0148 "http://www.w3.org/XML/1998/namespace:@lang";
  • 0149
  • 0150 /**
  • 0151 * Define the origin of the document from which the tree was built
  • 0152 */
  • 0153 public void setDocumentURI(String uri) {
  • 0154 if (uri != null) {
  • 0155 setDocumentBaseURI(SystemIDResolver.getAbsoluteURI(uri));
  • 0156 }
  • 0157 }
  • 0158
  • 0159 /**
  • 0160 * Returns the origin of the document from which the tree was built
  • 0161 */
  • 0162 public String getDocumentURI() {
  • 0163 String baseURI = getDocumentBaseURI();
  • 0164 return (baseURI != null) ? baseURI : "rtf" + _documentURIIndex++;
  • 0165 }
  • 0166
  • 0167 public String getDocumentURI(int node) {
  • 0168 return getDocumentURI();
  • 0169 }
  • 0170
  • 0171 public void setupMapping(String[] names, String[] urisArray,
  • 0172 int[] typesArray, String[] namespaces) {
  • 0173 // This method only has a function in DOM adapters
  • 0174 }
  • 0175
  • 0176 /**
  • 0177 * Lookup a namespace URI from a prefix starting at node. This method
  • 0178 * is used in the execution of xsl:element when the prefix is not known
  • 0179 * at compile time.
  • 0180 */
  • 0181 public String lookupNamespace(int node, String prefix)
  • 0182 throws TransletException
  • 0183 {
  • 0184 int anode, nsnode;
  • 0185 final AncestorIterator ancestors = new AncestorIterator();
  • 0186
  • 0187 if (isElement(node)) {
  • 0188 ancestors.includeSelf();
  • 0189 }
  • 0190
  • 0191 ancestors.setStartNode(node);
  • 0192 while ((anode = ancestors.next()) != DTM.NULL) {
  • 0193 final NamespaceIterator namespaces = new NamespaceIterator();
  • 0194
  • 0195 namespaces.setStartNode(anode);
  • 0196 while ((nsnode = namespaces.next()) != DTM.NULL) {
  • 0197 if (getLocalName(nsnode).equals(prefix)) {
  • 0198 return getNodeValue(nsnode);
  • 0199 }
  • 0200 }
  • 0201 }
  • 0202
  • 0203 BasisLibrary.runTimeError(BasisLibrary.NAMESPACE_PREFIX_ERR, prefix);
  • 0204 return null;
  • 0205 }
  • 0206
  • 0207 /**
  • 0208 * Returns 'true' if a specific node is an element (of any type)
  • 0209 */
  • 0210 public boolean isElement(final int node) {
  • 0211 return getNodeType(node) == DTM.ELEMENT_NODE;
  • 0212 }
  • 0213
  • 0214 /**
  • 0215 * Returns 'true' if a specific node is an attribute (of any type)
  • 0216 */
  • 0217 public boolean isAttribute(final int node) {
  • 0218 return getNodeType(node) == DTM.ATTRIBUTE_NODE;
  • 0219 }
  • 0220
  • 0221 /**
  • 0222 * Returns the number of nodes in the tree (used for indexing)
  • 0223 */
  • 0224 public int getSize() {
  • 0225 return getNumberOfNodes();
  • 0226 }
  • 0227
  • 0228 /**
  • 0229 * Part of the DOM interface - no function here.
  • 0230 */
  • 0231 public void setFilter(StripFilter filter) {
  • 0232 }
  • 0233
  • 0234
  • 0235 /**
  • 0236 * Returns true if node1 comes before node2 in document order
  • 0237 */
  • 0238 public boolean lessThan(int node1, int node2) {
  • 0239 if (node1 == DTM.NULL) {
  • 0240 return false;
  • 0241 }
  • 0242
  • 0243 if (node2 == DTM.NULL) {
  • 0244 return true;
  • 0245 }
  • 0246
  • 0247 return (node1 < node2);
  • 0248 }
  • 0249
  • 0250 /**
  • 0251 * Create an org.w3c.dom.Node from a node in the tree
  • 0252 */
  • 0253 public Node makeNode(int index) {
  • 0254 if (_nodes == null) {
  • 0255 _nodes = new Node[_namesSize];
  • 0256 }
  • 0257
  • 0258 int nodeID = makeNodeIdentity(index);
  • 0259 if (nodeID < 0) {
  • 0260 return null;
  • 0261 }
  • 0262 else if (nodeID < _nodes.length) {
  • 0263 return (_nodes[nodeID] != null) ? _nodes[nodeID]
  • 0264 : (_nodes[nodeID] = new DTMNodeProxy((DTM)this, index));
  • 0265 }
  • 0266 else {
  • 0267 return new DTMNodeProxy((DTM)this, index);
  • 0268 }
  • 0269 }
  • 0270
  • 0271 /**
  • 0272 * Create an org.w3c.dom.Node from a node in an iterator
  • 0273 * The iterator most be started before this method is called
  • 0274 */
  • 0275 public Node makeNode(DTMAxisIterator iter) {
  • 0276 return makeNode(iter.next());
  • 0277 }
  • 0278
  • 0279 /**
  • 0280 * Create an org.w3c.dom.NodeList from a node in the tree
  • 0281 */
  • 0282 public NodeList makeNodeList(int index) {
  • 0283 if (_nodeLists == null) {
  • 0284 _nodeLists = new NodeList[_namesSize];
  • 0285 }
  • 0286
  • 0287 int nodeID = makeNodeIdentity(index);
  • 0288 if (nodeID < 0) {
  • 0289 return null;
  • 0290 }
  • 0291 else if (nodeID < _nodeLists.length) {
  • 0292 return (_nodeLists[nodeID] != null) ? _nodeLists[nodeID]
  • 0293 : (_nodeLists[nodeID] = new DTMAxisIterNodeList(this,
  • 0294 new SingletonIterator(index)));
  • 0295 }
  • 0296 else {
  • 0297 return new DTMAxisIterNodeList(this, new SingletonIterator(index));
  • 0298 }
  • 0299 }
  • 0300
  • 0301 /**
  • 0302 * Create an org.w3c.dom.NodeList from a node iterator
  • 0303 * The iterator most be started before this method is called
  • 0304 */
  • 0305 public NodeList makeNodeList(DTMAxisIterator iter) {
  • 0306 return new DTMAxisIterNodeList(this, iter);
  • 0307 }
  • 0308
  • 0309 /**
  • 0310 * Iterator that returns the namespace nodes as defined by the XPath data
  • 0311 * model for a given node, filtered by extended type ID.
  • 0312 */
  • 0313 public class TypedNamespaceIterator extends NamespaceIterator {
  • 0314
  • 0315 private String _nsPrefix;
  • 0316
  • 0317 /**
  • 0318 * Constructor TypedChildrenIterator
  • 0319 *
  • 0320 *
  • 0321 * @param nodeType The extended type ID being requested.
  • 0322 */
  • 0323 public TypedNamespaceIterator(int nodeType) {
  • 0324 super();
  • 0325 if(m_expandedNameTable != null){
  • 0326 _nsPrefix = m_expandedNameTable.getLocalName(nodeType);
  • 0327 }
  • 0328 }
  • 0329
  • 0330 /**
  • 0331 * Get the next node in the iteration.
  • 0332 *
  • 0333 * @return The next node handle in the iteration, or END.
  • 0334 */
  • 0335 public int next() {
  • 0336 if ((_nsPrefix == null) ||(_nsPrefix.length() == 0) ){
  • 0337 return (END);
  • 0338 }
  • 0339 int node = END;
  • 0340 for (node = super.next(); node != END; node = super.next()) {
  • 0341 if (_nsPrefix.compareTo(getLocalName(node))== 0) {
  • 0342 return returnNode(node);
  • 0343 }
  • 0344 }
  • 0345 return (END);
  • 0346 }
  • 0347 } // end of TypedNamespaceIterator
  • 0348
  • 0349
  • 0350
  • 0351 /**************************************************************
  • 0352 * This is a specialised iterator for predicates comparing node or
  • 0353 * attribute values to variable or parameter values.
  • 0354 */
  • 0355 private final class NodeValueIterator extends InternalAxisIteratorBase
  • 0356 {
  • 0357
  • 0358 private DTMAxisIterator _source;
  • 0359 private String _value;
  • 0360 private boolean _op;
  • 0361 private final boolean _isReverse;
  • 0362 private int _returnType = RETURN_PARENT;
  • 0363
  • 0364 public NodeValueIterator(DTMAxisIterator source, int returnType,
  • 0365 String value, boolean op)
  • 0366 {
  • 0367 _source = source;
  • 0368 _returnType = returnType;
  • 0369 _value = value;
  • 0370 _op = op;
  • 0371 _isReverse = source.isReverse();
  • 0372 }
  • 0373
  • 0374 public boolean isReverse()
  • 0375 {
  • 0376 return _isReverse;
  • 0377 }
  • 0378
  • 0379 public DTMAxisIterator cloneIterator()
  • 0380 {
  • 0381 try {
  • 0382 NodeValueIterator clone = (NodeValueIterator)super.clone();
  • 0383 clone._isRestartable = false;
  • 0384 clone._source = _source.cloneIterator();
  • 0385 clone._value = _value;
  • 0386 clone._op = _op;
  • 0387 return clone.reset();
  • 0388 }
  • 0389 catch (CloneNotSupportedException e) {
  • 0390 BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
  • 0391 e.toString());
  • 0392 return null;
  • 0393 }
  • 0394 }
  • 0395
  • 0396 public void setRestartable(boolean isRestartable)
  • 0397 {
  • 0398 _isRestartable = isRestartable;
  • 0399 _source.setRestartable(isRestartable);
  • 0400 }
  • 0401
  • 0402 public DTMAxisIterator reset()
  • 0403 {
  • 0404 _source.reset();
  • 0405 return resetPosition();
  • 0406 }
  • 0407
  • 0408 public int next()
  • 0409 {
  • 0410 int node;
  • 0411 while ((node = _source.next()) != END) {
  • 0412 String val = getStringValueX(node);
  • 0413 if (_value.equals(val) == _op) {
  • 0414 if (_returnType == RETURN_CURRENT) {
  • 0415 return returnNode(node);
  • 0416 }
  • 0417 else {
  • 0418 return returnNode(getParent(node));
  • 0419 }
  • 0420 }
  • 0421 }
  • 0422 return END;
  • 0423 }
  • 0424
  • 0425 public DTMAxisIterator setStartNode(int node)
  • 0426 {
  • 0427 if (_isRestartable) {
  • 0428 _source.setStartNode(_startNode = node);
  • 0429 return resetPosition();
  • 0430 }
  • 0431 return this;
  • 0432 }
  • 0433
  • 0434 public void setMark()
  • 0435 {
  • 0436 _source.setMark();
  • 0437 }
  • 0438
  • 0439 public void gotoMark()
  • 0440 {
  • 0441 _source.gotoMark();
  • 0442 }
  • 0443 } // end NodeValueIterator
  • 0444
  • 0445 public DTMAxisIterator getNodeValueIterator(DTMAxisIterator iterator, int type,
  • 0446 String value, boolean op)
  • 0447 {
  • 0448 return(DTMAxisIterator)(new NodeValueIterator(iterator, type, value, op));
  • 0449 }
  • 0450
  • 0451 /**
  • 0452 * Encapsulates an iterator in an OrderedIterator to ensure node order
  • 0453 */
  • 0454 public DTMAxisIterator orderNodes(DTMAxisIterator source, int node)
  • 0455 {
  • 0456 return new DupFilterIterator(source);
  • 0457 }
  • 0458
  • 0459 /**
  • 0460 * Returns singleton iterator containg the document root
  • 0461 * Works for them main document (mark == 0). It cannot be made
  • 0462 * to point to any other node through setStartNode().
  • 0463 */
  • 0464 public DTMAxisIterator getIterator()
  • 0465 {
  • 0466 return new SingletonIterator(getDocument(), true);
  • 0467 }
  • 0468
  • 0469 /**
  • 0470 * Get mapping from DOM namespace types to external namespace types
  • 0471 */
  • 0472 public int getNSType(int node)
  • 0473 {
  • 0474 String s = getNamespaceURI(node);
  • 0475 if (s == null) {
  • 0476 return 0;
  • 0477 }
  • 0478 int eType = getIdForNamespace(s);
  • 0479 return ((Integer)_nsIndex.get(new Integer(eType))).intValue();
  • 0480 }
  • 0481
  • 0482
  • 0483
  • 0484 /**
  • 0485 * Returns the namespace type of a specific node
  • 0486 */
  • 0487 public int getNamespaceType(final int node)
  • 0488 {
  • 0489 return super.getNamespaceType(node);
  • 0490 }
  • 0491
  • 0492 /**
  • 0493 * Sets up a translet-to-dom type mapping table
  • 0494 */
  • 0495 private int[] setupMapping(String[] names, String[] uris, int[] types, int nNames) {
  • 0496 // Padding with number of names, because they
  • 0497 // may need to be added, i.e for RTFs. See copy03
  • 0498 final int[] result = new int[m_expandedNameTable.getSize()];
  • 0499 for (int i = 0; i < nNames; i++) {
  • 0500 //int type = getGeneralizedType(namesArray[i]);
  • 0501 int type = m_expandedNameTable.getExpandedTypeID(uris[i], names[i], types[i], false);
  • 0502 result[type] = type;
  • 0503 }
  • 0504 return result;
  • 0505 }
  • 0506
  • 0507 /**
  • 0508 * Returns the internal type associated with an expanded QName
  • 0509 */
  • 0510 public int getGeneralizedType(final String name) {
  • 0511 return getGeneralizedType(name, true);
  • 0512 }
  • 0513
  • 0514 /**
  • 0515 * Returns the internal type associated with an expanded QName
  • 0516 */
  • 0517 public int getGeneralizedType(final String name, boolean searchOnly) {
  • 0518 String lName, ns = null;
  • 0519 int index = -1;
  • 0520 int code;
  • 0521
  • 0522 // Is there a prefix?
  • 0523 if ((index = name.lastIndexOf(":"))> -1) {
  • 0524 ns = name.substring(0, index);
  • 0525 }
  • 0526
  • 0527 // Local part of name is after colon. lastIndexOf returns -1 if
  • 0528 // there is no colon, so lNameStartIdx will be zero in that case.
  • 0529 int lNameStartIdx = index+1;
  • 0530
  • 0531 // Distinguish attribute and element names. Attribute has @ before
  • 0532 // local part of name.
  • 0533 if (name.charAt(lNameStartIdx) == '@') {
  • 0534 code = DTM.ATTRIBUTE_NODE;
  • 0535 lNameStartIdx++;
  • 0536 }
  • 0537 else {
  • 0538 code = DTM.ELEMENT_NODE;
  • 0539 }
  • 0540
  • 0541 // Extract local name
  • 0542 lName = (lNameStartIdx == 0) ? name : name.substring(lNameStartIdx);
  • 0543
  • 0544 return m_expandedNameTable.getExpandedTypeID(ns, lName, code, searchOnly);
  • 0545 }
  • 0546
  • 0547 /**
  • 0548 * Get mapping from DOM element/attribute types to external types
  • 0549 */
  • 0550 public short[] getMapping(String[] names, String[] uris, int[] types)
  • 0551 {
  • 0552 // Delegate the work to getMapping2 if the document is not fully built.
  • 0553 // Some of the processing has to be different in this case.
  • 0554 if (_namesSize < 0) {
  • 0555 return getMapping2(names, uris, types);
  • 0556 }
  • 0557
  • 0558 int i;
  • 0559 final int namesLength = names.length;
  • 0560 final int exLength = m_expandedNameTable.getSize();
  • 0561
  • 0562 final short[] result = new short[exLength];
  • 0563
  • 0564 // primitive types map to themselves
  • 0565 for (i = 0; i < DTM.NTYPES; i++) {
  • 0566 result[i] = (short)i;
  • 0567 }
  • 0568
  • 0569 for (i = NTYPES; i < exLength; i++) {
  • 0570 result[i] = m_expandedNameTable.getType(i);
  • 0571 }
  • 0572
  • 0573 // actual mapping of caller requested names
  • 0574 for (i = 0; i < namesLength; i++) {
  • 0575 int genType = m_expandedNameTable.getExpandedTypeID(uris[i],
  • 0576 names[i],
  • 0577 types[i],
  • 0578 true);
  • 0579 if (genType >= 0 && genType < exLength) {
  • 0580 result[genType] = (short)(i + DTM.NTYPES);
  • 0581 }
  • 0582 }
  • 0583
  • 0584 return result;
  • 0585 }
  • 0586
  • 0587 /**
  • 0588 * Get mapping from external element/attribute types to DOM types
  • 0589 */
  • 0590 public int[] getReverseMapping(String[] names, String[] uris, int[] types)
  • 0591 {
  • 0592 int i;
  • 0593 final int[] result = new int[names.length + DTM.NTYPES];
  • 0594
  • 0595 // primitive types map to themselves
  • 0596 for (i = 0; i < DTM.NTYPES; i++) {
  • 0597 result[i] = i;
  • 0598 }
  • 0599
  • 0600 // caller's types map into appropriate dom types
  • 0601 for (i = 0; i < names.length; i++) {
  • 0602 int type = m_expandedNameTable.getExpandedTypeID(uris[i], names[i], types[i], true);
  • 0603 result[i+DTM.NTYPES] = type;
  • 0604 }
  • 0605 return(result);
  • 0606 }
  • 0607
  • 0608 /**
  • 0609 * Get mapping from DOM element/attribute types to external types.
  • 0610 * This method is used when the document is not fully built.
  • 0611 */
  • 0612 private short[] getMapping2(String[] names, String[] uris, int[] types)
  • 0613 {
  • 0614 int i;
  • 0615 final int namesLength = names.length;
  • 0616 final int exLength = m_expandedNameTable.getSize();
  • 0617 int[] generalizedTypes = null;
  • 0618 if (namesLength > 0) {
  • 0619 generalizedTypes = new int[namesLength];
  • 0620 }
  • 0621
  • 0622 int resultLength = exLength;
  • 0623
  • 0624 for (i = 0; i < namesLength; i++) {
  • 0625 // When the document is not fully built, the searchOnly
  • 0626 // flag should be set to false. That means we should add
  • 0627 // the type if it is not already in the expanded name table.
  • 0628 //generalizedTypes[i] = getGeneralizedType(names[i], false);
  • 0629 generalizedTypes[i] =
  • 0630 m_expandedNameTable.getExpandedTypeID(uris[i],
  • 0631 names[i],
  • 0632 types[i],
  • 0633 false);
  • 0634 if (_namesSize < 0 && generalizedTypes[i] >= resultLength) {
  • 0635 resultLength = generalizedTypes[i] + 1;
  • 0636 }
  • 0637 }
  • 0638
  • 0639 final short[] result = new short[resultLength];
  • 0640
  • 0641 // primitive types map to themselves
  • 0642 for (i = 0; i < DTM.NTYPES; i++) {
  • 0643 result[i] = (short)i;
  • 0644 }
  • 0645
  • 0646 for (i = NTYPES; i < exLength; i++) {
  • 0647 result[i] = m_expandedNameTable.getType(i);
  • 0648 }
  • 0649
  • 0650 // actual mapping of caller requested names
  • 0651 for (i = 0; i < namesLength; i++) {
  • 0652 int genType = generalizedTypes[i];
  • 0653 if (genType >= 0 && genType < resultLength) {
  • 0654 result[genType] = (short)(i + DTM.NTYPES);
  • 0655 }
  • 0656 }
  • 0657
  • 0658 return(result);
  • 0659 }
  • 0660 /**
  • 0661 * Get mapping from DOM namespace types to external namespace types
  • 0662 */
  • 0663 public short[] getNamespaceMapping(String[] namespaces)
  • 0664 {
  • 0665 int i;
  • 0666 final int nsLength = namespaces.length;
  • 0667 final int mappingLength = _uriCount;
  • 0668
  • 0669 final short[] result = new short[mappingLength];
  • 0670
  • 0671 // Initialize all entries to -1
  • 0672 for (i=0; i<mappingLength; i++) {
  • 0673 result[i] = (short)(-1);
  • 0674 }
  • 0675
  • 0676 for (i=0; i<nsLength; i++) {
  • 0677 int eType = getIdForNamespace(namespaces[i]);
  • 0678 Integer type = (Integer)_nsIndex.get(new Integer(eType));
  • 0679 if (type != null) {
  • 0680 result[type.intValue()] = (short)i;
  • 0681 }
  • 0682 }
  • 0683
  • 0684 return(result);
  • 0685 }
  • 0686
  • 0687 /**
  • 0688 * Get mapping from external namespace types to DOM namespace types
  • 0689 */
  • 0690 public short[] getReverseNamespaceMapping(String[] namespaces)
  • 0691 {
  • 0692 int i;
  • 0693 final int length = namespaces.length;
  • 0694 final short[] result = new short[length];
  • 0695
  • 0696 for (i = 0; i < length; i++) {
  • 0697 int eType = getIdForNamespace(namespaces[i]);
  • 0698 Integer type = (Integer)_nsIndex.get(new Integer(eType));
  • 0699 result[i] = (type == null) ? -1 : type.shortValue();
  • 0700 }
  • 0701
  • 0702 return result;
  • 0703 }
  • 0704
  • 0705 /**
  • 0706 * Construct a SAXImpl object using the default block size.
  • 0707 */
  • 0708 public SAXImpl(XSLTCDTMManager mgr, Source source,
  • 0709 int dtmIdentity, DTMWSFilter whiteSpaceFilter,
  • 0710 XMLStringFactory xstringfactory,
  • 0711 boolean doIndexing, boolean buildIdIndex)
  • 0712 {
  • 0713 this(mgr, source, dtmIdentity, whiteSpaceFilter, xstringfactory,
  • 0714 doIndexing, DEFAULT_BLOCKSIZE, buildIdIndex, false);
  • 0715 }
  • 0716
  • 0717 /**
  • 0718 * Construct a SAXImpl object using the given block size.
  • 0719 */
  • 0720 public SAXImpl(XSLTCDTMManager mgr, Source source,
  • 0721 int dtmIdentity, DTMWSFilter whiteSpaceFilter,
  • 0722 XMLStringFactory xstringfactory,
  • 0723 boolean doIndexing, int blocksize,
  • 0724 boolean buildIdIndex,
  • 0725 boolean newNameTable)
  • 0726 {
  • 0727 super(mgr, source, dtmIdentity, whiteSpaceFilter, xstringfactory,
  • 0728 doIndexing, blocksize, false, buildIdIndex, newNameTable);
  • 0729
  • 0730 _dtmManager = mgr;
  • 0731 _size = blocksize;
  • 0732
  • 0733 // Use a smaller size for the space stack if the blocksize is small
  • 0734 _xmlSpaceStack = new int[blocksize <= 64 ? 4 : 64];
  • 0735
  • 0736 /* From DOMBuilder */
  • 0737 _xmlSpaceStack[0] = DTMDefaultBase.ROOTNODE;
  • 0738
  • 0739 // If the input source is DOMSource, set the _document field and
  • 0740 // create the node2Ids table.
  • 0741 if (source instanceof DOMSource) {
  • 0742 _hasDOMSource = true;
  • 0743 DOMSource domsrc = (DOMSource)source;
  • 0744 Node node = domsrc.getNode();
  • 0745 if (node instanceof Document) {
  • 0746 _document = (Document)node;
  • 0747 }
  • 0748 else {
  • 0749 _document = node.getOwnerDocument();
  • 0750 }
  • 0751 _node2Ids = new Hashtable();
  • 0752 }
  • 0753 }
  • 0754
  • 0755 /**
  • 0756 * Migrate a DTM built with an old DTMManager to a new DTMManager.
  • 0757 * After the migration, the new DTMManager will treat the DTM as
  • 0758 * one that is built by itself.
  • 0759 * This is used to support DTM sharing between multiple transformations.
  • 0760 * @param manager the DTMManager
  • 0761 */
  • 0762 public void migrateTo(DTMManager manager) {
  • 0763 super.migrateTo(manager);
  • 0764 if (manager instanceof XSLTCDTMManager) {
  • 0765 _dtmManager = (XSLTCDTMManager)manager;
  • 0766 }
  • 0767 }
  • 0768
  • 0769 /**
  • 0770 * Return the node identity for a given id String
  • 0771 *
  • 0772 * @param idString The id String
  • 0773 * @return The identity of the node whose id is the given String.
  • 0774 */
  • 0775 public int getElementById(String idString)
  • 0776 {
  • 0777 Node node = _document.getElementById(idString);
  • 0778 if (node != null) {
  • 0779 Integer id = (Integer)_node2Ids.get(node);
  • 0780 return (id != null) ? id.intValue() : DTM.NULL;
  • 0781 }
  • 0782 else {
  • 0783 return DTM.NULL;
  • 0784 }
  • 0785 }
  • 0786
  • 0787 /**
  • 0788 * Return true if the input source is DOMSource.
  • 0789 */
  • 0790 public boolean hasDOMSource()
  • 0791 {
  • 0792 return _hasDOMSource;
  • 0793 }
  • 0794
  • 0795 /*---------------------------------------------------------------------------*/
  • 0796 /* DOMBuilder methods begin */
  • 0797 /*---------------------------------------------------------------------------*/
  • 0798
  • 0799 /**
  • 0800 * Call this when an xml:space attribute is encountered to
  • 0801 * define the whitespace strip/preserve settings.
  • 0802 */
  • 0803 private void xmlSpaceDefine(String val, final int node)
  • 0804 {
  • 0805 final boolean setting = val.equals(PRESERVE_STRING);
  • 0806 if (setting != _preserve) {
  • 0807 _xmlSpaceStack[_idx++] = node;
  • 0808 _preserve = setting;
  • 0809 }
  • 0810 }
  • 0811
  • 0812 /**
  • 0813 * Call this from endElement() to revert strip/preserve setting
  • 0814 * to whatever it was before the corresponding startElement().
  • 0815 */
  • 0816 private void xmlSpaceRevert(final int node)
  • 0817 {
  • 0818 if (node == _xmlSpaceStack[_idx - 1]) {
  • 0819 _idx--;
  • 0820 _preserve = !_preserve;
  • 0821 }
  • 0822 }
  • 0823
  • 0824 /**
  • 0825 * Find out whether or not to strip whitespace nodes.
  • 0826 *
  • 0827 *
  • 0828 * @return whether or not to strip whitespace nodes.
  • 0829 */
  • 0830 protected boolean getShouldStripWhitespace()
  • 0831 {
  • 0832 return _preserve ? false : super.getShouldStripWhitespace();
  • 0833 }
  • 0834
  • 0835 /**
  • 0836 * Creates a text-node and checks if it is a whitespace node.
  • 0837 */
  • 0838 private void handleTextEscaping() {
  • 0839 if (_disableEscaping && _textNodeToProcess != DTM.NULL
  • 0840 && _type(_textNodeToProcess) == DTM.TEXT_NODE) {
  • 0841 if (_dontEscape == null) {
  • 0842 _dontEscape = new BitArray(_size);
  • 0843 }
  • 0844
  • 0845 // Resize the _dontEscape BitArray if necessary.
  • 0846 if (_textNodeToProcess >= _dontEscape.size()) {
  • 0847 _dontEscape.resize(_dontEscape.size() * 2);
  • 0848 }
  • 0849
  • 0850 _dontEscape.setBit(_textNodeToProcess);
  • 0851 _disableEscaping = false;
  • 0852 }
  • 0853 _textNodeToProcess = DTM.NULL;
  • 0854 }
  • 0855
  • 0856
  • 0857 /****************************************************************/
  • 0858 /* SAX Interface Starts Here */
  • 0859 /****************************************************************/
  • 0860
  • 0861 /**
  • 0862 * SAX2: Receive notification of character data.
  • 0863 */
  • 0864 public void characters(char[] ch, int start, int length) throws SAXException
  • 0865 {
  • 0866 super.characters(ch, start, length);
  • 0867
  • 0868 _disableEscaping = !_escaping;
  • 0869 _textNodeToProcess = getNumberOfNodes();
  • 0870 }
  • 0871
  • 0872 /**
  • 0873 * SAX2: Receive notification of the beginning of a document.
  • 0874 */
  • 0875 public void startDocument() throws SAXException
  • 0876 {
  • 0877 super.startDocument();
  • 0878
  • 0879 _nsIndex.put(new Integer(0), new Integer(_uriCount++));
  • 0880 definePrefixAndUri(XML_PREFIX, XML_URI);
  • 0881 }
  • 0882
  • 0883 /**
  • 0884 * SAX2: Receive notification of the end of a document.
  • 0885 */
  • 0886 public void endDocument() throws SAXException
  • 0887 {
  • 0888 super.endDocument();
  • 0889
  • 0890 handleTextEscaping();
  • 0891 _namesSize = m_expandedNameTable.getSize();
  • 0892 }
  • 0893
  • 0894 /**
  • 0895 * Specialized interface used by DOM2SAX. This one has an extra Node
  • 0896 * parameter to build the Node -> id map.
  • 0897 */
  • 0898 public void startElement(String uri, String localName,
  • 0899 String qname, Attributes attributes,
  • 0900 Node node)
  • 0901 throws SAXException
  • 0902 {
  • 0903 this.startElement(uri, localName, qname, attributes);
  • 0904
  • 0905 if (m_buildIdIndex) {
  • 0906 _node2Ids.put(node, new Integer(m_parents.peek()));
  • 0907 }
  • 0908 }
  • 0909
  • 0910 /**
  • 0911 * SAX2: Receive notification of the beginning of an element.
  • 0912 */
  • 0913 public void startElement(String uri, String localName,
  • 0914 String qname, Attributes attributes)
  • 0915 throws SAXException
  • 0916 {
  • 0917 super.startElement(uri, localName, qname, attributes);
  • 0918
  • 0919 handleTextEscaping();
  • 0920
  • 0921 if (m_wsfilter != null) {
  • 0922 // Look for any xml:space attributes
  • 0923 // Depending on the implementation of attributes, this
  • 0924 // might be faster than looping through all attributes. ILENE
  • 0925 final int index = attributes.getIndex(XMLSPACE_STRING);
  • 0926 if (index >= 0) {
  • 0927 xmlSpaceDefine(attributes.getValue(index), m_parents.peek());
  • 0928 }
  • 0929 }
  • 0930 }
  • 0931
  • 0932 /**
  • 0933 * SAX2: Receive notification of the end of an element.
  • 0934 */
  • 0935 public void endElement(String namespaceURI, String localName, String qname)
  • 0936 throws SAXException
  • 0937 {
  • 0938 super.endElement(namespaceURI, localName, qname);
  • 0939
  • 0940 handleTextEscaping();
  • 0941
  • 0942 // Revert to strip/preserve-space setting from before this element
  • 0943 if (m_wsfilter != null) {
  • 0944 xmlSpaceRevert(m_previous);
  • 0945 }
  • 0946 }
  • 0947
  • 0948 /**
  • 0949 * SAX2: Receive notification of a processing instruction.
  • 0950 */
  • 0951 public void processingInstruction(String target, String data)
  • 0952 throws SAXException
  • 0953 {
  • 0954 super.processingInstruction(target, data);
  • 0955 handleTextEscaping();
  • 0956 }
  • 0957
  • 0958 /**
  • 0959 * SAX2: Receive notification of ignorable whitespace in element
  • 0960 * content. Similar to characters(char[], int, int).
  • 0961 */
  • 0962 public void ignorableWhitespace(char[] ch, int start, int length)
  • 0963 throws SAXException
  • 0964 {
  • 0965 super.ignorableWhitespace(ch, start, length);
  • 0966 _textNodeToProcess = getNumberOfNodes();
  • 0967 }
  • 0968
  • 0969 /**
  • 0970 * SAX2: Begin the scope of a prefix-URI Namespace mapping.
  • 0971 */
  • 0972 public void startPrefixMapping(String prefix, String uri)
  • 0973 throws SAXException
  • 0974 {
  • 0975 super.startPrefixMapping(prefix, uri);
  • 0976 handleTextEscaping();
  • 0977
  • 0978 definePrefixAndUri(prefix, uri);
  • 0979 }
  • 0980
  • 0981 private void definePrefixAndUri(String prefix, String uri)
  • 0982 throws SAXException
  • 0983 {
  • 0984 // Check if the URI already exists before pushing on stack
  • 0985 Integer eType = new Integer(getIdForNamespace(uri));
  • 0986 if ((Integer)_nsIndex.get(eType) == null) {
  • 0987 _nsIndex.put(eType, new Integer(_uriCount++));
  • 0988 }
  • 0989 }
  • 0990
  • 0991 /**
  • 0992 * SAX2: Report an XML comment anywhere in the document.
  • 0993 */
  • 0994 public void comment(char[] ch, int start, int length)
  • 0995 throws SAXException
  • 0996 {
  • 0997 super.comment(ch, start, length);
  • 0998 handleTextEscaping();
  • 0999 }
  • 1000
  • 1001 public boolean setEscaping(boolean value) {
  • 1002 final boolean temp = _escaping;
  • 1003 _escaping = value;
  • 1004 return temp;
  • 1005 }
  • 1006
  • 1007 /*---------------------------------------------------------------------------*/
  • 1008 /* DOMBuilder methods end */
  • 1009 /*---------------------------------------------------------------------------*/
  • 1010
  • 1011 /**
  • 1012 * Prints the whole tree to standard output
  • 1013 */
  • 1014 public void print(int node, int level)
  • 1015 {
  • 1016 switch(getNodeType(node))
  • 1017 {
  • 1018 case DTM.ROOT_NODE:
  • 1019 case DTM.DOCUMENT_NODE:
  • 1020 print(getFirstChild(node), level);
  • 1021 break;
  • 1022 case DTM.TEXT_NODE:
  • 1023 case DTM.COMMENT_NODE:
  • 1024 case DTM.PROCESSING_INSTRUCTION_NODE:
  • 1025 System.out.print(getStringValueX(node));
  • 1026 break;
  • 1027 default:
  • 1028 final String name = getNodeName(node);
  • 1029 System.out.print("<" + name);
  • 1030 for (int a = getFirstAttribute(node); a != DTM.NULL; a = getNextAttribute(a))
  • 1031 {
  • 1032 System.out.print("\n" + getNodeName(a) + "=\"" + getStringValueX(a) + "\"");
  • 1033 }
  • 1034 System.out.print('>');
  • 1035 for (int child = getFirstChild(node); child != DTM.NULL;
  • 1036 child = getNextSibling(child)) {
  • 1037 print(child, level + 1);
  • 1038 }
  • 1039 System.out.println("</" + name + '>');
  • 1040 break;
  • 1041 }
  • 1042 }
  • 1043
  • 1044 /**
  • 1045 * Returns the name of a node (attribute or element).
  • 1046 */
  • 1047 public String getNodeName(final int node)
  • 1048 {
  • 1049 // Get the node type and make sure that it is within limits
  • 1050 int nodeh = node;
  • 1051 final short type = getNodeType(nodeh);
  • 1052 switch(type)
  • 1053 {
  • 1054 case DTM.ROOT_NODE:
  • 1055 case DTM.DOCUMENT_NODE:
  • 1056 case DTM.TEXT_NODE:
  • 1057 case DTM.COMMENT_NODE:
  • 1058 return EMPTYSTRING;
  • 1059 case DTM.NAMESPACE_NODE:
  • 1060 return this.getLocalName(nodeh);
  • 1061 default:
  • 1062 return super.getNodeName(nodeh);
  • 1063 }
  • 1064 }
  • 1065
  • 1066 /**
  • 1067 * Returns the namespace URI to which a node belongs
  • 1068 */
  • 1069 public String getNamespaceName(final int node)
  • 1070 {
  • 1071 if (node == DTM.NULL) {
  • 1072 return "";
  • 1073 }
  • 1074
  • 1075 String s;
  • 1076 return (s = getNamespaceURI(node)) == null ? EMPTYSTRING : s;
  • 1077 }
  • 1078
  • 1079
  • 1080 /**
  • 1081 * Returns the attribute node of a given type (if any) for an element
  • 1082 */
  • 1083 public int getAttributeNode(final int type, final int element)
  • 1084 {
  • 1085 for (int attr = getFirstAttribute(element);
  • 1086 attr != DTM.NULL;
  • 1087 attr = getNextAttribute(attr))
  • 1088 {
  • 1089 if (getExpandedTypeID(attr) == type) return attr;
  • 1090 }
  • 1091 return DTM.NULL;
  • 1092 }
  • 1093
  • 1094 /**
  • 1095 * Returns the value of a given attribute type of a given element
  • 1096 */
  • 1097 public String getAttributeValue(final int type, final int element)
  • 1098 {
  • 1099 final int attr = getAttributeNode(type, element);
  • 1100 return (attr != DTM.NULL) ? getStringValueX(attr) : EMPTYSTRING;
  • 1101 }
  • 1102
  • 1103 /**
  • 1104 * This method is for testing/debugging only
  • 1105 */
  • 1106 public String getAttributeValue(final String name, final int element)
  • 1107 {
  • 1108 return getAttributeValue(getGeneralizedType(name), element);
  • 1109 }
  • 1110
  • 1111 /**
  • 1112 * Returns an iterator with all the children of a given node
  • 1113 */
  • 1114 public DTMAxisIterator getChildren(final int node)
  • 1115 {
  • 1116 return (new ChildrenIterator()).setStartNode(node);
  • 1117 }
  • 1118
  • 1119 /**
  • 1120 * Returns an iterator with all children of a specific type
  • 1121 * for a given node (element)
  • 1122 */
  • 1123 public DTMAxisIterator getTypedChildren(final int type)
  • 1124 {
  • 1125 return(new TypedChildrenIterator(type));
  • 1126 }
  • 1127
  • 1128 /**
  • 1129 * This is a shortcut to the iterators that implement the
  • 1130 * supported XPath axes (only namespace::) is not supported.
  • 1131 * Returns a bare-bones iterator that must be initialized
  • 1132 * with a start node (using iterator.setStartNode()).
  • 1133 */
  • 1134 public DTMAxisIterator getAxisIterator(final int axis)
  • 1135 {
  • 1136 switch (axis)
  • 1137 {
  • 1138 case Axis.SELF:
  • 1139 return new SingletonIterator();
  • 1140 case Axis.CHILD:
  • 1141 return new ChildrenIterator();
  • 1142 case Axis.PARENT:
  • 1143 return new ParentIterator();
  • 1144 case Axis.ANCESTOR:
  • 1145 return new AncestorIterator();
  • 1146 case Axis.ANCESTORORSELF:
  • 1147 return (new AncestorIterator()).includeSelf();
  • 1148 case Axis.ATTRIBUTE:
  • 1149 return new AttributeIterator();
  • 1150 case Axis.DESCENDANT:
  • 1151 return new DescendantIterator();
  • 1152 case Axis.DESCENDANTORSELF:
  • 1153 return (new DescendantIterator()).includeSelf();
  • 1154 case Axis.FOLLOWING:
  • 1155 return new FollowingIterator();
  • 1156 case Axis.PRECEDING:
  • 1157 return new PrecedingIterator();
  • 1158 case Axis.FOLLOWINGSIBLING:
  • 1159 return new FollowingSiblingIterator();
  • 1160 case Axis.PRECEDINGSIBLING:
  • 1161 return new PrecedingSiblingIterator();
  • 1162 case Axis.NAMESPACE:
  • 1163 return new NamespaceIterator();
  • 1164 case Axis.ROOT:
  • 1165 return new RootIterator();
  • 1166 default:
  • 1167 BasisLibrary.runTimeError(BasisLibrary.AXIS_SUPPORT_ERR,
  • 1168 Axis.getNames(axis));
  • 1169 }
  • 1170 return null;
  • 1171 }
  • 1172
  • 1173 /**
  • 1174 * Similar to getAxisIterator, but this one returns an iterator
  • 1175 * containing nodes of a typed axis (ex.: child::foo)
  • 1176 */
  • 1177 public DTMAxisIterator getTypedAxisIterator(int axis, int type)
  • 1178 {
  • 1179 // Most common case handled first
  • 1180 if (axis == Axis.CHILD) {
  • 1181 return new TypedChildrenIterator(type);
  • 1182 }
  • 1183
  • 1184 if (type == NO_TYPE) {
  • 1185 return(EMPTYITERATOR);
  • 1186 }
  • 1187
  • 1188 switch (axis)
  • 1189 {
  • 1190 case Axis.SELF:
  • 1191 return new TypedSingletonIterator(type);
  • 1192 case Axis.CHILD:
  • 1193 return new TypedChildrenIterator(type);
  • 1194 case Axis.PARENT:
  • 1195 return new ParentIterator().setNodeType(type);
  • 1196 case Axis.ANCESTOR:
  • 1197 return new TypedAncestorIterator(type);
  • 1198 case Axis.ANCESTORORSELF:
  • 1199 return (new TypedAncestorIterator(type)).includeSelf();
  • 1200 case Axis.ATTRIBUTE:
  • 1201 return new TypedAttributeIterator(type);
  • 1202 case Axis.DESCENDANT:
  • 1203 return new TypedDescendantIterator(type);
  • 1204 case Axis.DESCENDANTORSELF:
  • 1205 return (new TypedDescendantIterator(type)).includeSelf();
  • 1206 case Axis.FOLLOWING:
  • 1207 return new TypedFollowingIterator(type);
  • 1208 case Axis.PRECEDING:
  • 1209 return new TypedPrecedingIterator(type);
  • 1210 case Axis.FOLLOWINGSIBLING:
  • 1211 return new TypedFollowingSiblingIterator(type);
  • 1212 case Axis.PRECEDINGSIBLING:
  • 1213 return new TypedPrecedingSiblingIterator(type);
  • 1214 case Axis.NAMESPACE:
  • 1215 return new TypedNamespaceIterator(type);
  • 1216 case Axis.ROOT:
  • 1217 return new TypedRootIterator(type);
  • 1218 default:
  • 1219 BasisLibrary.runTimeError(BasisLibrary.TYPED_AXIS_SUPPORT_ERR,
  • 1220 Axis.getNames(axis));
  • 1221 }
  • 1222 return null;
  • 1223 }
  • 1224
  • 1225 /**
  • 1226 * Do not think that this returns an iterator for the namespace axis.
  • 1227 * It returns an iterator with nodes that belong in a certain namespace,
  • 1228 * such as with <xsl:apply-templates select="blob/foo:*"/>
  • 1229 * The 'axis' specifies the axis for the base iterator from which the
  • 1230 * nodes are taken, while 'ns' specifies the namespace URI type.
  • 1231 */
  • 1232 public DTMAxisIterator getNamespaceAxisIterator(int axis, int ns)
  • 1233 {
  • 1234
  • 1235 DTMAxisIterator iterator = null;
  • 1236
  • 1237 if (ns == NO_TYPE) {
  • 1238 return EMPTYITERATOR;
  • 1239 }
  • 1240 else {
  • 1241 switch (axis) {
  • 1242 case Axis.CHILD:
  • 1243 return new NamespaceChildrenIterator(ns);
  • 1244 case Axis.ATTRIBUTE:
  • 1245 return new NamespaceAttributeIterator(ns);
  • 1246 default:
  • 1247 return new NamespaceWildcardIterator(axis, ns);
  • 1248 }
  • 1249 }
  • 1250 }
  • 1251
  • 1252 /**
  • 1253 * Iterator that handles node tests that test for a namespace, but have
  • 1254 * a wild card for the local name of the node, i.e., node tests of the
  • 1255 * form <axis>::<prefix>:*
  • 1256 */
  • 1257 public final class NamespaceWildcardIterator
  • 1258 extends InternalAxisIteratorBase
  • 1259 {
  • 1260 /**
  • 1261 * The namespace type index.
  • 1262 */
  • 1263 protected int m_nsType;
  • 1264
  • 1265 /**
  • 1266 * A nested typed axis iterator that retrieves nodes of the principal
  • 1267 * node kind for that axis.
  • 1268 */
  • 1269 protected DTMAxisIterator m_baseIterator;
  • 1270
  • 1271 /**
  • 1272 * Constructor NamespaceWildcard
  • 1273 *
  • 1274 * @param axis The axis that this iterator will traverse
  • 1275 * @param nsType The namespace type index
  • 1276 */
  • 1277 public NamespaceWildcardIterator(int axis, int nsType) {
  • 1278 m_nsType = nsType;
  • 1279
  • 1280 // Create a nested iterator that will select nodes of
  • 1281 // the principal node kind for the selected axis.
  • 1282 switch (axis) {
  • 1283 case Axis.ATTRIBUTE: {
  • 1284 // For "attribute::p:*", the principal node kind is
  • 1285 // attribute
  • 1286 m_baseIterator = getAxisIterator(axis);
  • 1287 }
  • 1288 case Axis.NAMESPACE: {
  • 1289 // This covers "namespace::p:*". It is syntactically
  • 1290 // correct, though it doesn't make much sense.
  • 1291 m_baseIterator = getAxisIterator(axis);
  • 1292 }
  • 1293 default: {
  • 1294 // In all other cases, the principal node kind is
  • 1295 // element
  • 1296 m_baseIterator = getTypedAxisIterator(axis,
  • 1297 DTM.ELEMENT_NODE);
  • 1298 }
  • 1299 }
  • 1300 }
  • 1301
  • 1302 /**
  • 1303 * Set start to END should 'close' the iterator,
  • 1304 * i.e. subsequent call to next() should return END.
  • 1305 *
  • 1306 * @param node Sets the root of the iteration.
  • 1307 *
  • 1308 * @return A DTMAxisIterator set to the start of the iteration.
  • 1309 */
  • 1310 public DTMAxisIterator setStartNode(int node) {
  • 1311 if (_isRestartable) {
  • 1312 _startNode = node;
  • 1313 m_baseIterator.setStartNode(node);
  • 1314 resetPosition();
  • 1315 }
  • 1316 return this;
  • 1317 }
  • 1318
  • 1319 /**
  • 1320 * Get the next node in the iteration.
  • 1321 *
  • 1322 * @return The next node handle in the iteration, or END.
  • 1323 */
  • 1324 public int next() {
  • 1325 int node;
  • 1326
  • 1327 while ((node = m_baseIterator.next()) != END) {
  • 1328 // Return only nodes that are in the selected namespace
  • 1329 if (getNSType(node) == m_nsType) {
  • 1330 return returnNode(node);
  • 1331 }
  • 1332 }
  • 1333
  • 1334 return END;
  • 1335 }
  • 1336
  • 1337 /**
  • 1338 * Returns a deep copy of this iterator. The cloned iterator is not
  • 1339 * reset.
  • 1340 *
  • 1341 * @return a deep copy of this iterator.
  • 1342 */
  • 1343 public DTMAxisIterator cloneIterator() {
  • 1344 try {
  • 1345 DTMAxisIterator nestedClone = m_baseIterator.cloneIterator();
  • 1346 NamespaceWildcardIterator clone =
  • 1347 (NamespaceWildcardIterator) super.clone();
  • 1348
  • 1349 clone.m_baseIterator = nestedClone;
  • 1350 clone.m_nsType = m_nsType;
  • 1351 clone._isRestartable = false;
  • 1352
  • 1353 return clone;
  • 1354 } catch (CloneNotSupportedException e) {
  • 1355 BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
  • 1356 e.toString());
  • 1357 return null;
  • 1358 }
  • 1359 }
  • 1360
  • 1361 /**
  • 1362 * True if this iterator has a reversed axis.
  • 1363 *
  • 1364 * @return <code>true</code> if this iterator is a reversed axis.
  • 1365 */
  • 1366 public boolean isReverse() {
  • 1367 return m_baseIterator.isReverse();
  • 1368 }
  • 1369
  • 1370 public void setMark() {
  • 1371 m_baseIterator.setMark();
  • 1372 }
  • 1373
  • 1374 public void gotoMark() {
  • 1375 m_baseIterator.gotoMark();
  • 1376 }
  • 1377 }
  • 1378
  • 1379 /**
  • 1380 * Iterator that returns children within a given namespace for a
  • 1381 * given node. The functionality chould be achieved by putting a
  • 1382 * filter on top of a basic child iterator, but a specialised
  • 1383 * iterator is used for efficiency (both speed and size of translet).
  • 1384 */
  • 1385 public final class NamespaceChildrenIterator
  • 1386 extends InternalAxisIteratorBase
  • 1387 {
  • 1388
  • 1389 /** The extended type ID being requested. */
  • 1390 private final int _nsType;
  • 1391
  • 1392 /**
  • 1393 * Constructor NamespaceChildrenIterator
  • 1394 *
  • 1395 *
  • 1396 * @param type The extended type ID being requested.
  • 1397 */
  • 1398 public NamespaceChildrenIterator(final int type) {
  • 1399 _nsType = type;
  • 1400 }
  • 1401
  • 1402 /**
  • 1403 * Set start to END should 'close' the iterator,
  • 1404 * i.e. subsequent call to next() should return END.
  • 1405 *
  • 1406 * @param node Sets the root of the iteration.
  • 1407 *
  • 1408 * @return A DTMAxisIterator set to the start of the iteration.
  • 1409 */
  • 1410 public DTMAxisIterator setStartNode(int node) {
  • 1411 //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
  • 1412 if (node == DTMDefaultBase.ROOTNODE) {
  • 1413 node = getDocument();
  • 1414 }
  • 1415
  • 1416 if (_isRestartable) {
  • 1417 _startNode = node;
  • 1418 _currentNode = (node == DTM.NULL) ? DTM.NULL : NOTPROCESSED;
  • 1419
  • 1420 return resetPosition();
  • 1421 }
  • 1422
  • 1423 return this;
  • 1424 }
  • 1425
  • 1426 /**
  • 1427 * Get the next node in the iteration.
  • 1428 *
  • 1429 * @return The next node handle in the iteration, or END.
  • 1430 */
  • 1431 public int next() {
  • 1432 if (_currentNode != DTM.NULL) {
  • 1433 for (int node = (NOTPROCESSED == _currentNode)
  • 1434 ? _firstch(makeNodeIdentity(_startNode))
  • 1435 : _nextsib(_currentNode);
  • 1436 node != END;
  • 1437 node = _nextsib(node)) {
  • 1438 int nodeHandle = makeNodeHandle(node);
  • 1439
  • 1440 if (getNSType(nodeHandle) == _nsType) {
  • 1441 _currentNode = node;
  • 1442
  • 1443 return returnNode(nodeHandle);
  • 1444 }
  • 1445 }
  • 1446 }
  • 1447
  • 1448 return END;
  • 1449 }
  • 1450 } // end of NamespaceChildrenIterator
  • 1451
  • 1452 /**
  • 1453 * Iterator that returns attributes within a given namespace for a node.
  • 1454 */
  • 1455 public final class NamespaceAttributeIterator
  • 1456 extends InternalAxisIteratorBase
  • 1457 {
  • 1458
  • 1459 /** The extended type ID being requested. */
  • 1460 private final int _nsType;
  • 1461
  • 1462 /**
  • 1463 * Constructor NamespaceAttributeIterator
  • 1464 *
  • 1465 *
  • 1466 * @param nsType The extended type ID being requested.
  • 1467 */
  • 1468 public NamespaceAttributeIterator(int nsType) {
  • 1469 super();
  • 1470
  • 1471 _nsType = nsType;
  • 1472 }
  • 1473
  • 1474 /**
  • 1475 * Set start to END should 'close' the iterator,
  • 1476 * i.e. subsequent call to next() should return END.
  • 1477 *
  • 1478 * @param node Sets the root of the iteration.
  • 1479 *
  • 1480 * @return A DTMAxisIterator set to the start of the iteration.
  • 1481 */
  • 1482 public DTMAxisIterator setStartNode(int node) {
  • 1483 //%HZ%: Added reference to DTMDefaultBase.ROOTNODE back in, temporarily
  • 1484 if (node == DTMDefaultBase.ROOTNODE) {
  • 1485 node = getDocument();
  • 1486 }
  • 1487
  • 1488 if (_isRestartable) {
  • 1489 int nsType = _nsType;
  • 1490
  • 1491 _startNode = node;
  • 1492
  • 1493 for (node = getFirstAttribute(node);
  • 1494 node != END;
  • 1495 node = getNextAttribute(node)) {
  • 1496 if (getNSType(node) == nsType) {
  • 1497 break;
  • 1498 }
  • 1499 }
  • 1500
  • 1501 _currentNode = node;
  • 1502 return resetPosition();
  • 1503 }
  • 1504
  • 1505 return this;
  • 1506 }
  • 1507
  • 1508 /**
  • 1509 * Get the next node in the iteration.
  • 1510 *
  • 1511 * @return The next node handle in the iteration, or END.
  • 1512 */
  • 1513 public int next() {
  • 1514 int node = _currentNode;
  • 1515 int nsType = _nsType;
  • 1516 int nextNode;
  • 1517
  • 1518 if (node == END) {
  • 1519 return END;
  • 1520 }
  • 1521
  • 1522 for (nextNode = getNextAttribute(node);
  • 1523 nextNode != END;
  • 1524 nextNode = getNextAttribute(nextNode)) {
  • 1525 if (getNSType(nextNode) == nsType) {
  • 1526 break;
  • 1527 }
  • 1528 }
  • 1529
  • 1530 _currentNode = nextNode;
  • 1531
  • 1532 return returnNode(node);
  • 1533 }
  • 1534 } // end of NamespaceAttributeIterator
  • 1535
  • 1536 /**
  • 1537 * Returns an iterator with all descendants of a node that are of
  • 1538 * a given type.
  • 1539 */
  • 1540 public DTMAxisIterator getTypedDescendantIterator(int type)
  • 1541 {
  • 1542 return new TypedDescendantIterator(type);
  • 1543 }
  • 1544
  • 1545 /**
  • 1546 * Returns the nth descendant of a node
  • 1547 */
  • 1548 public DTMAxisIterator getNthDescendant(int type, int n, boolean includeself)
  • 1549 {
  • 1550 DTMAxisIterator source = (DTMAxisIterator) new TypedDescendantIterator(type);
  • 1551 return new NthDescendantIterator(n);
  • 1552 }
  • 1553
  • 1554 /**
  • 1555 * Copy the string value of a node directly to an output handler
  • 1556 */
  • 1557 public void characters(final int node, SerializationHandler handler)
  • 1558 throws TransletException
  • 1559 {
  • 1560 if (node != DTM.NULL) {
  • 1561 try {
  • 1562 dispatchCharactersEvents(node, handler, false);
  • 1563 } catch (SAXException e) {
  • 1564 throw new TransletException(e);
  • 1565 }
  • 1566 }
  • 1567 }
  • 1568
  • 1569 /**
  • 1570 * Copy a node-set to an output handler
  • 1571 */
  • 1572 public void copy(DTMAxisIterator nodes, SerializationHandler handler)
  • 1573 throws TransletException
  • 1574 {
  • 1575 int node;
  • 1576 while ((node = nodes.next()) != DTM.NULL) {
  • 1577 copy(node, handler);
  • 1578 }
  • 1579 }
  • 1580
  • 1581 /**
  • 1582 * Copy the whole tree to an output handler
  • 1583 */
  • 1584 public void copy(SerializationHandler handler) throws TransletException
  • 1585 {
  • 1586 copy(getDocument(), handler);
  • 1587 }
  • 1588
  • 1589 /**
  • 1590 * Performs a deep copy (ref. XSLs copy-of())
  • 1591 *
  • 1592 * TODO: Copy namespace declarations. Can't be done until we
  • 1593 * add namespace nodes and keep track of NS prefixes
  • 1594 * TODO: Copy comment nodes
  • 1595 */
  • 1596 public void copy(final int node, SerializationHandler handler)
  • 1597 throws TransletException
  • 1598 {
  • 1599 copy(node, handler, false );
  • 1600 }
  • 1601
  • 1602
  • 1603 private final void copy(final int node, SerializationHandler handler, boolean isChild)
  • 1604 throws TransletException
  • 1605 {
  • 1606 int nodeID = makeNodeIdentity(node);
  • 1607 int eType = _exptype2(nodeID);
  • 1608 int type = _exptype2Type(eType);
  • 1609
  • 1610 try {
  • 1611 switch(type)
  • 1612 {
  • 1613 case DTM.ROOT_NODE:
  • 1614 case DTM.DOCUMENT_NODE:
  • 1615 for(int c = _firstch2(nodeID); c != DTM.NULL; c = _nextsib2(c)) {
  • 1616 copy(makeNodeHandle(c), handler, true);
  • 1617 }
  • 1618 break;
  • 1619 case DTM.PROCESSING_INSTRUCTION_NODE:
  • 1620 copyPI(node, handler);
  • 1621 break;
  • 1622 case DTM.COMMENT_NODE:
  • 1623 handler.comment(getStringValueX(node));
  • 1624 break;
  • 1625 case DTM.TEXT_NODE:
  • 1626 boolean oldEscapeSetting = false;
  • 1627 boolean escapeBit = false;
  • 1628
  • 1629 if (_dontEscape != null) {
  • 1630 escapeBit = _dontEscape.getBit(getNodeIdent(node));
  • 1631 if (escapeBit) {
  • 1632 oldEscapeSetting = handler.setEscaping(false);
  • 1633 }
  • 1634 }
  • 1635
  • 1636 copyTextNode(nodeID, handler);
  • 1637
  • 1638 if (escapeBit) {
  • 1639 handler.setEscaping(oldEscapeSetting);
  • 1640 }
  • 1641 break;
  • 1642 case DTM.ATTRIBUTE_NODE:
  • 1643 copyAttribute(nodeID, eType, handler);
  • 1644 break;
  • 1645 case DTM.NAMESPACE_NODE:
  • 1646 handler.namespaceAfterStartElement(getNodeNameX(node), getNodeValue(node));
  • 1647 break;
  • 1648 default:
  • 1649 if (type == DTM.ELEMENT_NODE)
  • 1650 {
  • 1651 // Start element definition
  • 1652 final String name = copyElement(nodeID, eType, handler);
  • 1653 //if(isChild) => not to copy any namespaces from parents
  • 1654 // else copy all namespaces in scope
  • 1655 copyNS(nodeID, handler,!isChild);
  • 1656 copyAttributes(nodeID, handler);
  • 1657 // Copy element children
  • 1658 for (int c = _firstch2(nodeID); c != DTM.NULL; c = _nextsib2(c)) {
  • 1659 copy(makeNodeHandle(c), handler, true);
  • 1660 }
  • 1661
  • 1662 // Close element definition
  • 1663 handler.endElement(name);
  • 1664 }
  • 1665 // Shallow copy of attribute to output handler
  • 1666 else {
  • 1667 final String uri = getNamespaceName(node);
  • 1668 if (uri.length() != 0) {
  • 1669 final String prefix = getPrefix(node);
  • 1670 handler.namespaceAfterStartElement(prefix, uri);
  • 1671 }
  • 1672 handler.addAttribute(getNodeName(node), getNodeValue(node));
  • 1673 }
  • 1674 break;
  • 1675 }
  • 1676 }
  • 1677 catch (Exception e) {
  • 1678 throw new TransletException(e);
  • 1679 }
  • 1680
  • 1681 }
  • 1682 /**
  • 1683 * Copies a processing instruction node to an output handler
  • 1684 */
  • 1685 private void copyPI(final int node, SerializationHandler handler)
  • 1686 throws TransletException
  • 1687 {
  • 1688 final String target = getNodeName(node);
  • 1689 final String value = getStringValueX(node);
  • 1690
  • 1691 try {
  • 1692 handler.processingInstruction(target, value);
  • 1693 } catch (Exception e) {
  • 1694 throw new TransletException(e);
  • 1695 }
  • 1696 }
  • 1697
  • 1698 /**
  • 1699 * Performs a shallow copy (ref. XSLs copy())
  • 1700 */
  • 1701 public String shallowCopy(final int node, SerializationHandler handler)
  • 1702 throws TransletException
  • 1703 {
  • 1704 int nodeID = makeNodeIdentity(node);
  • 1705 int exptype = _exptype2(nodeID);
  • 1706 int type = _exptype2Type(exptype);
  • 1707
  • 1708 try {
  • 1709 switch(type)
  • 1710 {
  • 1711 case DTM.ELEMENT_NODE:
  • 1712 final String name = copyElement(nodeID, exptype, handler);
  • 1713 copyNS(nodeID, handler, true);
  • 1714 return name;
  • 1715 case DTM.ROOT_NODE:
  • 1716 case DTM.DOCUMENT_NODE:
  • 1717 return EMPTYSTRING;
  • 1718 case DTM.TEXT_NODE:
  • 1719 copyTextNode(nodeID, handler);
  • 1720 return null;
  • 1721 case DTM.PROCESSING_INSTRUCTION_NODE:
  • 1722 copyPI(node, handler);
  • 1723 return null;
  • 1724 case DTM.COMMENT_NODE:
  • 1725 handler.comment(getStringValueX(node));
  • 1726 return null;
  • 1727 case DTM.NAMESPACE_NODE:
  • 1728 handler.namespaceAfterStartElement(getNodeNameX(node), getNodeValue(node));
  • 1729 return null;
  • 1730 case DTM.ATTRIBUTE_NODE:
  • 1731 copyAttribute(nodeID, exptype, handler);
  • 1732 return null;
  • 1733 default:
  • 1734 final String uri1 = getNamespaceName(node);
  • 1735 if (uri1.length() != 0) {
  • 1736 final String prefix = getPrefix(node);
  • 1737 handler.namespaceAfterStartElement(prefix, uri1);
  • 1738 }
  • 1739 handler.addAttribute(getNodeName(node), getNodeValue(node));
  • 1740 return null;
  • 1741 }
  • 1742 } catch (Exception e) {
  • 1743 throw new TransletException(e);
  • 1744 }
  • 1745 }
  • 1746
  • 1747 /**
  • 1748 * Returns a node' defined language for a node (if any)
  • 1749 */
  • 1750 public String getLanguage(int node)
  • 1751 {
  • 1752 int parent = node;
  • 1753 while (DTM.NULL != parent) {
  • 1754 if (DTM.ELEMENT_NODE == getNodeType(parent)) {
  • 1755 int langAttr = getAttributeNode(parent, "http://www.w3.org/XML/1998/namespace", "lang");
  • 1756
  • 1757 if (DTM.NULL != langAttr) {
  • 1758 return getNodeValue(langAttr);
  • 1759 }
  • 1760 }
  • 1761
  • 1762 parent = getParent(parent);
  • 1763 }
  • 1764 return(null);
  • 1765 }
  • 1766
  • 1767 /**
  • 1768 * Returns an instance of the DOMBuilder inner class
  • 1769 * This class will consume the input document through a SAX2
  • 1770 * interface and populate the tree.
  • 1771 */
  • 1772 public DOMBuilder getBuilder()
  • 1773 {
  • 1774 return this;
  • 1775 }
  • 1776
  • 1777 /**
  • 1778 * Return a SerializationHandler for output handling.
  • 1779 * This method is used by Result Tree Fragments.
  • 1780 */
  • 1781 public SerializationHandler getOutputDomBuilder()
  • 1782 {
  • 1783 return new ToXMLSAXHandler(this, "UTF-8");
  • 1784 }
  • 1785
  • 1786 /**
  • 1787 * Return a instance of a DOM class to be used as an RTF
  • 1788 */
  • 1789 public DOM getResultTreeFrag(int initSize, int rtfType)
  • 1790 {
  • 1791 return getResultTreeFrag(initSize, rtfType, true);
  • 1792 }
  • 1793
  • 1794 /**
  • 1795 * Return a instance of a DOM class to be used as an RTF
  • 1796 *
  • 1797 * @param initSize The initial size of the DOM.
  • 1798 * @param rtfType The type of the RTF
  • 1799 * @param addToManager true if the RTF should be registered with the DTMManager.
  • 1800 * @return The DOM object which represents the RTF.
  • 1801 */
  • 1802 public DOM getResultTreeFrag(int initSize, int rtfType, boolean addToManager)
  • 1803 {
  • 1804 if (rtfType == DOM.SIMPLE_RTF) {
  • 1805 if (addToManager) {
  • 1806 int dtmPos = _dtmManager.getFirstFreeDTMID();
  • 1807 SimpleResultTreeImpl rtf = new SimpleResultTreeImpl(_dtmManager,
  • 1808 dtmPos << DTMManager.IDENT_DTM_NODE_BITS);
  • 1809 _dtmManager.addDTM(rtf, dtmPos, 0);
  • 1810 return rtf;
  • 1811 }
  • 1812 else {
  • 1813 return new SimpleResultTreeImpl(_dtmManager, 0);
  • 1814 }
  • 1815 }
  • 1816 else if (rtfType == DOM.ADAPTIVE_RTF) {
  • 1817 if (addToManager) {
  • 1818 int dtmPos = _dtmManager.getFirstFreeDTMID();
  • 1819 AdaptiveResultTreeImpl rtf = new AdaptiveResultTreeImpl(_dtmManager,
  • 1820 dtmPos << DTMManager.IDENT_DTM_NODE_BITS,
  • 1821 m_wsfilter, initSize, m_buildIdIndex);
  • 1822 _dtmManager.addDTM(rtf, dtmPos, 0);
  • 1823 return rtf;
  • 1824
  • 1825 }
  • 1826 else {
  • 1827 return new AdaptiveResultTreeImpl(_dtmManager, 0,
  • 1828 m_wsfilter, initSize, m_buildIdIndex);
  • 1829 }
  • 1830 }
  • 1831 else {
  • 1832 return (DOM) _dtmManager.getDTM(null, true, m_wsfilter,
  • 1833 true, false, false,
  • 1834 initSize, m_buildIdIndex);
  • 1835 }
  • 1836 }
  • 1837
  • 1838 /**
  • 1839 * %HZ% Need Javadoc
  • 1840 */
  • 1841 public Hashtable getElementsWithIDs() {
  • 1842 if (m_idAttributes == null) {
  • 1843 return null;
  • 1844 }
  • 1845
  • 1846 // Convert a java.util.Hashtable to an xsltc.runtime.Hashtable
  • 1847 Enumeration idValues = m_idAttributes.keys();
  • 1848 if (!idValues.hasMoreElements()) {
  • 1849 return null;
  • 1850 }
  • 1851
  • 1852 Hashtable idAttrsTable = new Hashtable();
  • 1853
  • 1854 while (idValues.hasMoreElements()) {
  • 1855 Object idValue = idValues.nextElement();
  • 1856
  • 1857 idAttrsTable.put(idValue, m_idAttributes.get(idValue));
  • 1858 }
  • 1859
  • 1860 return idAttrsTable;
  • 1861 }
  • 1862
  • 1863 /**
  • 1864 * The getUnparsedEntityURI function returns the URI of the unparsed
  • 1865 * entity with the specified name in the same document as the context
  • 1866 * node (see [3.3 Unparsed Entities]). It returns the empty string if
  • 1867 * there is no such entity.
  • 1868 */
  • 1869 public String getUnparsedEntityURI(String name)
  • 1870 {
  • 1871 // Special handling for DOM input
  • 1872 if (_document != null) {
  • 1873 String uri = "";
  • 1874 DocumentType doctype = _document.getDoctype();
  • 1875 if (doctype != null) {
  • 1876 NamedNodeMap entities = doctype.getEntities();
  • 1877
  • 1878 if (entities == null) {
  • 1879 return uri;
  • 1880 }
  • 1881
  • 1882 Entity entity = (Entity) entities.getNamedItem(name);
  • 1883
  • 1884 if (entity == null) {
  • 1885 return uri;
  • 1886 }
  • 1887
  • 1888 String notationName = entity.getNotationName();
  • 1889 if (notationName != null) {
  • 1890 uri = entity.getSystemId();
  • 1891 if (uri == null) {
  • 1892 uri = entity.getPublicId();
  • 1893 }
  • 1894 }
  • 1895 }
  • 1896 return uri;
  • 1897 }
  • 1898 else {
  • 1899 return super.getUnparsedEntityURI(name);
  • 1900 }
  • 1901 }
  • 1902
  • 1903}

文件:SAXImpl.java
包名:com.sun.org.apache.xalan.internal.xsltc.dom
类名:SAXImpl
继承:SAX2DTM2
接口:[DOMEnhancedForDTM][DOMBuilder]