- /*
- * 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.31 2004/02/16 22:54:59 minchau 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.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) {
- AdaptiveResultTreeImpl adaptiveRTF = (AdaptiveResultTreeImpl)dom;
- DOM nestedDom = adaptiveRTF.getNestedDOM();
- if (nestedDom != null) {
- DOMAdapter newAdapter = new DOMAdapter(nestedDom,
- adapter.getNamesArray(),
- adapter.getUrisArray(),
- adapter.getTypesArray(),
- adapter.getNamespaceArray());
- addDOMAdapter(newAdapter);
- }
- }
-
- return domNo;
- }
-
- public int getDocumentMask(String uri) {
- Integer domIdx = (Integer)_documents.get(uri);
- if (domIdx == null) {
- return(-1);
- } else {
- return domIdx.intValue();
- }
- }
-
- public DOM getDOMAdapter(String uri) {
- Integer domIdx = (Integer)_documents.get(uri);
- if (domIdx == null) {
- return(null);
- } else {
- return(_adapters[domIdx.intValue()]);
- }
- }
-
- public int getDocument()
- {
- return _main.getDocument();
- }
-
- public DTMManager getDTMManager() {
- return _dtmManager;
- }
-
- /**
- * Returns singleton iterator containing the document root
- */
- public DTMAxisIterator getIterator() {
- // main source document @ 0
- return _main.getIterator();
- }
-
- public String getStringValue() {
- return _main.getStringValue();
- }
-
- public DTMAxisIterator getChildren(final int node) {
- return _adapters[getDTMId(node)].getChildren(node);
- }
-
- public DTMAxisIterator getTypedChildren(final int type) {
- return new AxisIterator(Axis.CHILD, type);
- }
-
- public DTMAxisIterator getAxisIterator(final int axis) {
- return new AxisIterator(axis, NO_TYPE);
- }
-
- public DTMAxisIterator getTypedAxisIterator(final int axis, final int type)
- {
- return new AxisIterator(axis, type);
- }
-
- public DTMAxisIterator getNthDescendant(int node, int n,
- boolean includeself)
- {
- return _adapters[getDTMId(node)].getNthDescendant(node, n, includeself);
- }
-
- public DTMAxisIterator getNodeValueIterator(DTMAxisIterator iterator,
- int type, String value,
- boolean op)
- {
- return(new NodeValueIterator(iterator, type, value, op));
- }
-
- public DTMAxisIterator getNamespaceAxisIterator(final int axis,
- final int ns)
- {
- DTMAxisIterator iterator = _main.getNamespaceAxisIterator(axis, ns);
- return(iterator);
- }
-
- public DTMAxisIterator orderNodes(DTMAxisIterator source, int node) {
- return _adapters[getDTMId(node)].orderNodes(source, node);
- }
-
- public int getExpandedTypeID(final int node) {
- if (node != DTM.NULL) {
- return _adapters[node >>> DTMManager.IDENT_DTM_NODE_BITS].getExpandedTypeID(node);
- }
- else {
- return DTM.NULL;
- }
- }
-
- public int getNamespaceType(final int node) {
- return _adapters[getDTMId(node)].getNamespaceType(node);
- }
-
- public int getNSType(int node)
- {
- return _adapters[getDTMId(node)].getNSType(node);
- }
-
- public int getParent(final int node) {
- if (node == DTM.NULL) {
- return DTM.NULL;
- }
- return _adapters[node >>> DTMManager.IDENT_DTM_NODE_BITS].getParent(node);
- }
-
- public int getAttributeNode(final int type, final int el) {
- if (el == DTM.NULL) {
- return DTM.NULL;
- }
- return _adapters[el >>> DTMManager.IDENT_DTM_NODE_BITS].getAttributeNode(type, el);
- }
-
- public String getNodeName(final int node) {
- if (node == DTM.NULL) {
- return "";
- }
- return _adapters[node >>> DTMManager.IDENT_DTM_NODE_BITS].getNodeName(node);
- }
-
- public String getNodeNameX(final int node) {
- if (node == DTM.NULL) {
- return "";
- }
- return _adapters[node >>> DTMManager.IDENT_DTM_NODE_BITS].getNodeNameX(node);
- }
-
- public String getNamespaceName(final int node) {
- if (node == DTM.NULL) {
- return "";
- }
- return _adapters[node >>> DTMManager.IDENT_DTM_NODE_BITS].getNamespaceName(node);
- }
-
- public String getStringValueX(final int node) {
- if (node == DTM.NULL) {
- return "";
- }
- return _adapters[node >>> DTMManager.IDENT_DTM_NODE_BITS].getStringValueX(node);
- }
-
- public void copy(final int node, SerializationHandler handler)
- throws TransletException
- {
- if (node != DTM.NULL) {
- _adapters[node >>> DTMManager.IDENT_DTM_NODE_BITS].copy(node, handler);
- }
- }
-
- public void copy(DTMAxisIterator nodes, SerializationHandler handler)
- throws TransletException
- {
- int node;
- while ((node = nodes.next()) != DTM.NULL) {
- _adapters[node >>> DTMManager.IDENT_DTM_NODE_BITS].copy(node, handler);
- }
- }
-
-
- public String shallowCopy(final int node, SerializationHandler handler)
- throws TransletException
- {
- if (node == DTM.NULL) {
- return "";
- }
- return _adapters[node >>> DTMManager.IDENT_DTM_NODE_BITS].shallowCopy(node, handler);
- }
-
- public boolean lessThan(final int node1, final int node2) {
- if (node1 == DTM.NULL) {
- return true;
- }
- if (node2 == DTM.NULL) {
- return false;
- }
- final int dom1 = getDTMId(node1);
- final int dom2 = getDTMId(node2);
- return dom1 == dom2 ? _adapters[dom1].lessThan(node1, node2)
- : dom1 < dom2;
- }
-
- public void characters(final int textNode, SerializationHandler handler)
- throws TransletException
- {
- if (textNode != DTM.NULL) {
- _adapters[textNode >>> DTMManager.IDENT_DTM_NODE_BITS].characters(textNode, handler);
- }
- }
-
- public void setFilter(StripFilter filter) {
- for (int dom=0; dom<_free; dom++) {
- if (_adapters[dom] != null) {
- _adapters[dom].setFilter(filter);
- }
- }
- }
-
- public Node makeNode(int index) {
- if (index == DTM.NULL) {
- return null;
- }
- return _adapters[getDTMId(index)].makeNode(index);
- }
-
- public Node makeNode(DTMAxisIterator iter) {
- // TODO: gather nodes from all DOMs ?
- return _main.makeNode(iter);
- }
-
- public NodeList makeNodeList(int index) {
- if (index == DTM.NULL) {
- return null;
- }
- return _adapters[getDTMId(index)].makeNodeList(index);
- }
-
- public NodeList makeNodeList(DTMAxisIterator iter) {
- // TODO: gather nodes from all DOMs ?
- return _main.makeNodeList(iter);
- }
-
- public String getLanguage(int node) {
- return _adapters[getDTMId(node)].getLanguage(node);
- }
-
- public int getSize() {
- int size = 0;
- for (int i=0; i<_size; i++) {
- size += _adapters[i].getSize();
- }
- return(size);
- }
-
- public String getDocumentURI(int node) {
- if (node == DTM.NULL) {
- node = DOM.NULL;
- }
- return _adapters[node >>> DTMManager.IDENT_DTM_NODE_BITS].getDocumentURI(0);
- }
-
- public boolean isElement(final int node) {
- if (node == DTM.NULL) {
- return false;
- }
- return(_adapters[node >>> DTMManager.IDENT_DTM_NODE_BITS].isElement(node));
- }
-
- public boolean isAttribute(final int node) {
- if (node == DTM.NULL) {
- return false;
- }
- return(_adapters[node >>> DTMManager.IDENT_DTM_NODE_BITS].isAttribute(node));
- }
-
- public int getDTMId(int nodeHandle)
- {
- if (nodeHandle == DTM.NULL)
- return 0;
-
- int id = nodeHandle >>> DTMManager.IDENT_DTM_NODE_BITS;
- while (id >= 2 && _adapters[id] == _adapters[id-1]) {
- id--;
- }
- return id;
- }
-
- public int getNodeIdent(int nodeHandle)
- {
- return _adapters[nodeHandle >>> DTMManager.IDENT_DTM_NODE_BITS].getNodeIdent(nodeHandle);
- }
-
- public int getNodeHandle(int nodeId)
- {
- return _main.getNodeHandle(nodeId);
- }
-
- public DOM getResultTreeFrag(int initSize, int rtfType)
- {
- return _main.getResultTreeFrag(initSize, rtfType);
- }
-
- public DOM getResultTreeFrag(int initSize, int rtfType, boolean addToManager)
- {
- return _main.getResultTreeFrag(initSize, rtfType, addToManager);
- }
-
- public DOM getMain()
- {
- return _main;
- }
-
- /**
- * Returns a DOMBuilder class wrapped in a SAX adapter.
- */
- public SerializationHandler getOutputDomBuilder()
- {
- return _main.getOutputDomBuilder();
- }
-
- public String lookupNamespace(int node, String prefix)
- throws TransletException
- {
- return _main.lookupNamespace(node, prefix);
- }
-
- // %HZ% Does this method make any sense here???
- public String getUnparsedEntityURI(String entity) {
- return _main.getUnparsedEntityURI(entity);
- }
-
- // %HZ% Does this method make any sense here???
- public Hashtable getElementsWithIDs() {
- return _main.getElementsWithIDs();
- }
- }