📄 multidom.java
字号:
/* * 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: MultiDOM.java,v 1.5 2005/09/28 13:48:36 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.StripFilter;import com.sun.org.apache.xml.internal.serializer.SerializationHandler;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.Axis;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.ref.DTMAxisIteratorBase;import com.sun.org.apache.xml.internal.dtm.ref.DTMDefaultBase;import com.sun.org.apache.xml.internal.utils.SuballocatedIntVector;import org.w3c.dom.Node;import org.w3c.dom.NodeList;/** * @author Jacek Ambroziak * @author Morten Jorgensen * @author Erwin Bolwidt <ejb@klomp.org> */public final class MultiDOM implements DOM { private static final int NO_TYPE = DOM.FIRST_TYPE - 2; private static final int INITIAL_SIZE = 4; private DOM[] _adapters; private DOMAdapter _main; private DTMManager _dtmManager; private int _free; private int _size; private Hashtable _documents = new Hashtable(); private final class AxisIterator extends DTMAxisIteratorBase { // constitutive data private final int _axis; private final int _type; // implementation mechanism private DTMAxisIterator _source; private int _dtmId = -1; public AxisIterator(final int axis, final int type) { _axis = axis; _type = type; } public int next() { if (_source == null) { return(END); } return _source.next(); } public void setRestartable(boolean flag) { if (_source != null) { _source.setRestartable(flag); } } public DTMAxisIterator setStartNode(final int node) { if (node == DTM.NULL) { return this; } int dom = node >>> DTMManager.IDENT_DTM_NODE_BITS; // Get a new source first time and when mask changes if (_source == null || _dtmId != dom) { if (_type == NO_TYPE) { _source = _adapters[dom].getAxisIterator(_axis); } else if (_axis == Axis.CHILD) { _source = _adapters[dom].getTypedChildren(_type); } else { _source = _adapters[dom].getTypedAxisIterator(_axis, _type); } } _dtmId = dom; _source.setStartNode(node); return this; } public DTMAxisIterator reset() { if (_source != null) { _source.reset(); } return this; } public int getLast() { if (_source != null) { return _source.getLast(); } else { return END; } } public int getPosition() { if (_source != null) { return _source.getPosition(); } else { return END; } } public boolean isReverse() { return Axis.isReverse(_axis); } public void setMark() { if (_source != null) { _source.setMark(); } } public void gotoMark() { if (_source != null) { _source.gotoMark(); } } public DTMAxisIterator cloneIterator() { final AxisIterator clone = new AxisIterator(_axis, _type); if (_source != null) { clone._source = _source.cloneIterator(); } clone._dtmId = _dtmId; return clone; } } // end of AxisIterator /************************************************************** * This is a specialised iterator for predicates comparing node or * attribute values to variable or parameter values. */ private final class NodeValueIterator extends DTMAxisIteratorBase { 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._source = _source.cloneIterator(); clone.setRestartable(false); 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(); } } public MultiDOM(DOM main) { _size = INITIAL_SIZE; _free = 1; _adapters = new DOM[INITIAL_SIZE]; DOMAdapter adapter = (DOMAdapter)main; _adapters[0] = adapter; _main = adapter; DOM dom = adapter.getDOMImpl(); if (dom instanceof DTMDefaultBase) { _dtmManager = ((DTMDefaultBase)dom).getManager(); } // %HZ% %REVISIT% Is this the right thing to do here? In the old // %HZ% %REVISIT% version, the main document did not get added through // %HZ% %REVISIT% a call to addDOMAdapter, which meant it couldn't be // %HZ% %REVISIT% found by a call to getDocumentMask. The problem is // %HZ% %REVISIT% TransformerHandler is typically constructed with a // %HZ% %REVISIT% system ID equal to the stylesheet's URI; with SAX // %HZ% %REVISIT% input, it ends up giving that URI to the document. // %HZ% %REVISIT% Then, any references to document('') are resolved // %HZ% %REVISIT% using the stylesheet's URI. // %HZ% %REVISIT% MultiDOM.getDocumentMask is called to verify that // %HZ% %REVISIT% a document associated with that URI has not been // %HZ% %REVISIT% encountered, and that method ends up returning the // %HZ% %REVISIT% mask of the main document, when what we really what // %HZ% %REVISIT% is to read the stylesheet itself! addDOMAdapter(adapter, false); } public int nextMask() { return _free; } public void setupMapping(String[] names, String[] uris, int[] types, String[] namespaces) { // This method only has a function in DOM adapters } public int addDOMAdapter(DOMAdapter adapter) { return addDOMAdapter(adapter, true); } private int addDOMAdapter(DOMAdapter adapter, boolean indexByURI) { // Add the DOM adapter to the array of DOMs DOM dom = adapter.getDOMImpl(); int domNo = 1; int dtmSize = 1; SuballocatedIntVector dtmIds = null; if (dom instanceof DTMDefaultBase) { DTMDefaultBase dtmdb = (DTMDefaultBase)dom; dtmIds = dtmdb.getDTMIDs(); dtmSize = dtmIds.size(); domNo = dtmIds.elementAt(dtmSize-1) >>> DTMManager.IDENT_DTM_NODE_BITS; } else if (dom instanceof SimpleResultTreeImpl) { SimpleResultTreeImpl simpleRTF = (SimpleResultTreeImpl)dom; domNo = simpleRTF.getDocument() >>> DTMManager.IDENT_DTM_NODE_BITS; } if (domNo >= _size) { int oldSize = _size; do { _size *= 2; } while (_size <= domNo); final DOMAdapter[] newArray = new DOMAdapter[_size]; System.arraycopy(_adapters, 0, newArray, 0, oldSize); _adapters = newArray; } _free = domNo + 1; if (dtmSize == 1) { _adapters[domNo] = adapter; } else if (dtmIds != null) { int domPos = 0; for (int i = dtmSize - 1; i >= 0; i--) { domPos = dtmIds.elementAt(i) >>> DTMManager.IDENT_DTM_NODE_BITS; _adapters[domPos] = adapter; } domNo = domPos; } // Store reference to document (URI) in hashtable if (indexByURI) { String uri = adapter.getDocumentURI(0); _documents.put(uri, new Integer(domNo)); } // If the dom is an AdaptiveResultTreeImpl, we need to create a // DOMAdapter around its nested dom object (if it is non-null) and // add the DOMAdapter to the list. if (dom instanceof AdaptiveResultTreeImpl) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -