ilene 2002/09/20 06:48:48 Modified: java/src/org/apache/xpath/res XPATHErrorResources.java XPATHErrorResources.properties Added: java/src/org/apache/xpath/domapi XPathExpressionImpl.java XPathResultImpl.java XPathNSResolverImpl.java XPathEvaluatorImpl.java Log: Prototype implementation of DOM L3 XPath Specification. Revision Changes Path 1.1 xml-xalan/java/src/org/apache/xpath/domapi/XPathExpressionImpl.java Index: XPathExpressionImpl.java =================================================================== /* * The Apache Software License, Version 1.1 * * * Copyright (c) 2002 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Xalan" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 1999, Lotus * Development Corporation., http://www.lotus.com. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.xpath.domapi; import javax.xml.transform.TransformerException; import org.apache.xalan.res.XSLMessages; import org.apache.xml.utils.PrefixResolver; import org.apache.xpath.XPath; import org.apache.xpath.XPathContext; import org.apache.xpath.objects.XObject; import org.apache.xpath.res.XPATHErrorResources; import org.w3c.dom.DOMException; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.xpath.XPathException; import org.w3c.dom.xpath.XPathExpression; import org.w3c.dom.xpath.XPathNamespace; import org.w3c.dom.xpath.XPathResult; /** * * The class provides an implementation of XPathExpression according * to the DOM L3 XPath Specification, Working Draft 28, March 2002. * * <p>See also the <a href='http://www.w3.org/TR/2002/WD-DOM-Level-3-XPath-20020328'>Document Object Model (DOM) Level 3 XPath Specification</a>.</p> * <p>The <code>XPathExpression</code> interface represents a parsed and resolved * XPath expression.</p> * * @see org.w3c.dom.xpath.XPathExpression */ public class XPathExpressionImpl implements XPathExpression { private PrefixResolver m_resolver; /** * The xpath object that this expression wraps */ private XPath m_xpath; /** * The document to be searched to parallel the case where the XPathEvaluator * is obtained by casting a Document. */ private Document m_doc = null; /** * Constructor for XPathExpressionImpl. * * @param xpath The wrapped XPath object. * @param doc The document to be searched, to parallel the case where'' * the XPathEvaluator is obtained by casting the document. */ XPathExpressionImpl(XPath xpath, Document doc) { m_xpath = xpath; m_doc = doc; } /** * <meta name="usage" content="experimental"/> * * This method provides an implementation XPathResult.evaluate according * to the DOM L3 XPath Specification, Working Draft 28, March 2002. * * <p>See also the <a href='http://www.w3.org/TR/2002/WD-DOM-Level-3-XPath-20020328'>Document Object Model (DOM) Level 3 XPath Specification</a>.</p> * * <p>Evaluates this XPath expression and returns a result.</p> * @param contextNode The <code>context</code> is context node for the * evaluation of this XPath expression.If the XPathEvaluator was * obtained by casting the <code>Document</code> then this must be * owned by the same document and must be a <code>Document</code>, * <code>Element</code>, <code>Attribute</code>, <code>Text</code>, * <code>CDATASection</code>, <code>Comment</code>, * <code>ProcessingInstruction</code>, or <code>XPathNamespace</code> * node.If the context node is a <code>Text</code> or a * <code>CDATASection</code>, then the context is interpreted as the * whole logical text node as seen by XPath, unless the node is empty * in which case it may not serve as the XPath context. * @param type If a specific <code>type</code> is specified, then the * result will be coerced to return the specified type relying on * XPath conversions and fail if the desired coercion is not possible. * This must be one of the type codes of <code>XPathResult</code>. * @param result The <code>result</code> specifies a specific result * object which may be reused and returned by this method. If this is * specified as <code>null</code>or the implementation does not reuse * the specified result, a new result object will be constructed and * returned.For XPath 1.0 results, this object will be of type * <code>XPathResult</code>. * @return The result of the evaluation of the XPath expression.For XPath * 1.0 results, this object will be of type <code>XPathResult</code>. * @exception XPathException * TYPE_ERR: Raised if the result cannot be converted to return the * specified type. * @exception DOMException * WRONG_DOCUMENT_ERR: The Node is from a document that is not supported * by the XPathEvaluator that created this * <code>XPathExpression</code>. * <br>NOT_SUPPORTED_ERR: The Node is not a type permitted as an XPath * context node. * * @see org.w3c.dom.xpath.XPathExpression#evaluate(Node, short, XPathResult) */ public Object evaluate( Node contextNode, short type, Object result) throws XPathException, DOMException { // If the XPathEvaluator was determined by "casting" the document if (m_doc != null) { // Check that the context node is owned by the same document if ((contextNode != m_doc) && (!contextNode.getOwnerDocument().equals(m_doc))) { String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_WRONG_DOCUMENT, null); throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, fmsg); } // Check that the context node is an acceptable node type short nodeType = contextNode.getNodeType(); if ((nodeType != Document.DOCUMENT_NODE) && (nodeType != Document.ELEMENT_NODE) && (nodeType != Document.ATTRIBUTE_NODE) && (nodeType != Document.TEXT_NODE) && (nodeType != Document.CDATA_SECTION_NODE) && (nodeType != Document.COMMENT_NODE) && (nodeType != Document.PROCESSING_INSTRUCTION_NODE) && (nodeType != XPathNamespace.XPATH_NAMESPACE_NODE)) { String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_WRONG_NODETYPE, null); throw new DOMException(DOMException.NOT_SUPPORTED_ERR, fmsg); } } // // If the type is not a supported type, throw an exception and be // done with it! if (!XPathResultImpl.isValidType(type)) { String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_INVALID_XPATH_TYPE, new Object[] {new Integer(type)}); throw new XPathException(XPathException.TYPE_ERR,fmsg); // Invalid XPath type argument: {0} } // Cache xpath context? XPathContext xpathSupport = new XPathContext(); // if m_document is not null, build the DTM from the document if (null != m_doc) { xpathSupport.getDTMHandleFromNode(m_doc); } XObject xobj = null; try { xobj = m_xpath.execute(xpathSupport, contextNode, m_resolver ); } catch (TransformerException te) { // What should we do here? throw new XPathException(XPathException.INVALID_EXPRESSION_ERR,te.getMessageAndLocation()); } // Create a new XPathResult object // Reuse result object passed in? // The constructor will check the compatibility of type and xobj and // throw an exception if they are not compatible. return new XPathResultImpl(type,xobj,contextNode); } } 1.1 xml-xalan/java/src/org/apache/xpath/domapi/XPathResultImpl.java Index: XPathResultImpl.java =================================================================== /* * The Apache Software License, Version 1.1 * * * Copyright (c) 2002 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Xalan" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 1999, Lotus * Development Corporation., http://www.lotus.com. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.xpath.domapi; import javax.xml.transform.TransformerException; import org.apache.xalan.res.XSLMessages; import org.apache.xpath.objects.XObject; import org.apache.xpath.res.XPATHErrorResources; import org.w3c.dom.DOMException; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.events.Event; import org.w3c.dom.events.EventListener; import org.w3c.dom.events.EventTarget; import org.w3c.dom.traversal.NodeIterator; import org.w3c.dom.xpath.XPathException; import org.w3c.dom.xpath.XPathResult; /** * <meta name="usage" content="experimental"/> * * The class provides an implementation XPathResult according * to the DOM L3 XPath Specification, Working Draft 28, March 2002. * * <p>See also the <a href='http://www.w3.org/TR/2002/WD-DOM-Level-3-XPath-20020328'>Document Object Model (DOM) Level 3 XPath Specification</a>.</p> * * <p>The <code>XPathResult</code> interface represents the result of the * evaluation of an XPath expression within the context of a particular * node. Since evaluation of an XPath expression can result in various * result types, this object makes it possible to discover and manipulate * the type and value of the result.</p> * * <p>This implementation wraps an <code>XObject</code>. * * @see org.apache.xpath.objects.XObject * @see org.w3c.dom.xpath.XPathResult * */ public class XPathResultImpl implements XPathResult, EventListener { /** * The wrapped XObject */ private XObject m_resultObj; /** * This the type specified by the user during construction. Typically * the constructor will be called by org.apache.xpath.XPath.evaluate(). */ private short m_resultType = ANY_TYPE; private boolean m_isInvalidIteratorState = false; /** * Only used to attach a mutation event handler when specified * type is an iterator type. */ private Node m_contextNode; /** * The iterator, if this is an iterator type. */ private NodeIterator m_iterator = null; /** * The list, if this is a snapshot type. */ private NodeList m_list = null; /** * Constructor for XPathResultImpl. * * For internal use only. */ XPathResultImpl(short type, XObject result, Node contextNode) { // Check that the type is valid if (!isValidType(type)) { String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_INVALID_XPATH_TYPE, new Object[] {new Integer(type)}); throw new XPathException(XPathException.TYPE_ERR,fmsg); // Invalid XPath type argument: {0} } // Result object should never be null! if (null == result) { String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_EMPTY_XPATH_RESULT, null); throw new XPathException(XPathException.INVALID_EXPRESSION_ERR,fmsg); // Empty XPath result object } this.m_resultObj = result; this.m_contextNode = contextNode; // If specified result was ANY_TYPE, determine XObject type if (type == ANY_TYPE) { this.m_resultType = getTypeFromXObject(result); } else { this.m_resultType = type; } // If the context node supports DOM Events and the type is one of the iterator // types register this result as an event listener if (((m_resultType == XPathResult.ORDERED_NODE_ITERATOR_TYPE) || (m_resultType == XPathResult.UNORDERED_NODE_ITERATOR_TYPE))&& (contextNode instanceof EventTarget)) { ((EventTarget)contextNode).addEventListener("MutationEvents",this,true); }// else can we handle iterator types if contextNode doesn't support EventTarget?? // If this is an iterator type get the iterator if ((m_resultType == ORDERED_NODE_ITERATOR_TYPE) || (m_resultType == UNORDERED_NODE_ITERATOR_TYPE) || (m_resultType == ANY_UNORDERED_NODE_TYPE) || (m_resultType == FIRST_ORDERED_NODE_TYPE)) { try { m_iterator = m_resultObj.nodeset(); } catch (TransformerException te) { // probably not a node type String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_INCOMPATIBLE_TYPES, new Object[] {getTypeString(getTypeFromXObject(m_resultObj)),getTypeString(m_resultType)}); throw new XPathException(XPathException.TYPE_ERR, fmsg); // The returned type: {0} can not be coerced into the specified type: {1} } // If user requested ordered nodeset and result is unordered // need to sort...TODO // if ((m_resultType == ORDERED_NODE_ITERATOR_TYPE) && // (!(((DTMNodeIterator)m_iterator).getDTMIterator().isDocOrdered()))) { // // } // If it's a snapshot type, get the nodelist } else if ((m_resultType == UNORDERED_NODE_SNAPSHOT_TYPE) || (m_resultType == ORDERED_NODE_SNAPSHOT_TYPE)) { try { m_list = m_resultObj.nodelist(); } catch (TransformerException te) { // probably not a node type String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_INCOMPATIBLE_TYPES, new Object[] {getTypeString(getTypeFromXObject(m_resultObj)),getTypeString(m_resultType)}); throw new XPathException(XPathException.TYPE_ERR, fmsg); // The returned type: {0} can not be coerced into the specified type: {1} } } } /** * @see org.w3c.dom.xpath.XPathResult#getResultType() */ public short getResultType() { return m_resultType; } /** * The value of this number result. * @exception XPathException * TYPE_ERR: raised if <code>resultType</code> is not * <code>NUMBER_TYPE</code>. * @see org.w3c.dom.xpath.XPathResult#getNumberValue() */ public double getNumberValue() throws XPathException { if (getResultType() != NUMBER_TYPE) { String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CANT_CONVERT_TO_NUMBER, new Object[] {getTypeString(m_resultType)}); throw new XPathException(XPathException.TYPE_ERR,fmsg); // Can not convert {0} to a number } else { try { return m_resultObj.num(); } catch (Exception e) { // Type check above should prevent this exception from occurring. throw new XPathException(XPathException.TYPE_ERR,e.getMessage()); } } } /** * The value of this string result. * @exception XPathException * TYPE_ERR: raised if <code>resultType</code> is not * <code>STRING_TYPE</code>. * * @see org.w3c.dom.xpath.XPathResult#getStringValue() */ public String getStringValue() throws XPathException { if (getResultType() != STRING_TYPE) { String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CANT_CONVERT_TO_STRING, new Object[] {m_resultObj.getTypeString()}); throw new XPathException(XPathException.TYPE_ERR,fmsg); // Can not convert {0} to a string. } else { try { return m_resultObj.str(); } catch (Exception e) { // Type check above should prevent this exception from occurring. throw new XPathException(XPathException.TYPE_ERR,e.getMessage()); } } } /** * @see org.w3c.dom.xpath.XPathResult#getBooleanValue() */ public boolean getBooleanValue() throws XPathException { if (getResultType() != BOOLEAN_TYPE) { String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CANT_CONVERT_TO_BOOLEAN, new Object[] {getTypeString(m_resultType)}); throw new XPathException(XPathException.TYPE_ERR,fmsg); // Can not convert {0} to a boolean } else { try { return m_resultObj.bool(); } catch (TransformerException e) { // Type check above should prevent this exception from occurring. throw new XPathException(XPathException.TYPE_ERR,e.getMessage()); } } } /** * The value of this single node result, which may be <code>null</code>. * @exception XPathException * TYPE_ERR: raised if <code>resultType</code> is not * <code>ANY_UNORDERED_NODE_TYPE</code> or * <code>FIRST_ORDERED_NODE_TYPE</code>. * * @see org.w3c.dom.xpath.XPathResult#getSingleNodeValue() */ public Node getSingleNodeValue() throws XPathException { if ((m_resultType != ANY_UNORDERED_NODE_TYPE) && (m_resultType != FIRST_ORDERED_NODE_TYPE)) { String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CANT_CONVERT_TO_SINGLENODE, new Object[] {getTypeString(m_resultType)}); throw new XPathException(XPathException.TYPE_ERR,fmsg); // Can not convert {0} to a single node. This getter applies to types // ANY_UNORDERED_NODE_TYPE and FIRST_ORDERED_NODE_TYPE. } NodeIterator result = null; try { result = m_resultObj.nodeset(); } catch (TransformerException te) { throw new XPathException(XPathException.TYPE_ERR,te.getMessage()); } return (null == result) ? null : result.nextNode(); } /** * @see org.w3c.dom.xpath.XPathResult#getInvalidIteratorState() */ public boolean getInvalidIteratorState() { return m_isInvalidIteratorState; } /** * The number of nodes in the result snapshot. Valid values for * snapshotItem indices are <code>0</code> to * <code>snapshotLength-1</code> inclusive. * @exception XPathException * TYPE_ERR: raised if <code>resultType</code> is not * <code>UNORDERED_NODE_SNAPSHOT_TYPE</code> or * <code>ORDERED_NODE_SNAPSHOT_TYPE</code>. * * @see org.w3c.dom.xpath.XPathResult#getSnapshotLength() */ public int getSnapshotLength() throws XPathException { if ((m_resultType != UNORDERED_NODE_SNAPSHOT_TYPE) && (m_resultType != ORDERED_NODE_SNAPSHOT_TYPE)) { String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CANT_GET_SNAPSHOT_LENGTH, new Object[] {getTypeString(m_resultType)}); throw new XPathException(XPathException.TYPE_ERR,fmsg); // Can not get snapshot length on type: {0}. This getter applies to types //UNORDERED_NODE_SNAPSHOT_TYPE and ORDERED_NODE_SNAPSHOT_TYPE. } return m_list.getLength(); } /** * Iterates and returns the next node from the node set or * <code>null</code>if there are no more nodes. * @return Returns the next node. * @exception XPathException * TYPE_ERR: raised if <code>resultType</code> is not * <code>UNORDERED_NODE_ITERATOR_TYPE</code> or * <code>ORDERED_NODE_ITERATOR_TYPE</code>. * @exception DOMException * INVALID_STATE_ERR: The document has been mutated since the result was * returned. * @see org.w3c.dom.xpath.XPathResult#iterateNext() */ public Node iterateNext() throws XPathException, DOMException { if ((m_resultType != UNORDERED_NODE_ITERATOR_TYPE) && (m_resultType != ORDERED_NODE_ITERATOR_TYPE)) { String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NON_ITERATOR_TYPE, new Object[] {getTypeString(m_resultType)}); throw new XPathException(XPathException.TYPE_ERR, fmsg); // Can not iterate over non iterator type: {0} } if (getInvalidIteratorState()) { String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_DOC_MUTATED, null); throw new DOMException(DOMException.INVALID_STATE_ERR,fmsg); // Document mutated since result was returned. Iterator is invalid. } return m_iterator.nextNode(); } /** * Returns the <code>index</code>th item in the snapshot collection. If * <code>index</code> is greater than or equal to the number of nodes in * the list, this method returns <code>null</code>. Unlike the iterator * result, the snapshot does not become invalid, but may not correspond * to the current document if it is mutated. * @param index Index into the snapshot collection. * @return The node at the <code>index</code>th position in the * <code>NodeList</code>, or <code>null</code> if that is not a valid * index. * @exception XPathException * TYPE_ERR: raised if <code>resultType</code> is not * <code>UNORDERED_NODE_SNAPSHOT_TYPE</code> or * <code>ORDERED_NODE_SNAPSHOT_TYPE</code>. * * @see org.w3c.dom.xpath.XPathResult#snapshotItem(int) */ public Node snapshotItem(int index) throws XPathException { if ((m_resultType != UNORDERED_NODE_SNAPSHOT_TYPE) && (m_resultType != ORDERED_NODE_SNAPSHOT_TYPE)) { String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NON_SNAPSHOT_TYPE, new Object[] {getTypeString(m_resultType)}); throw new XPathException(XPathException.TYPE_ERR, fmsg); // Can call snapshotItem on type: {0}. This method applies to types // UNORDERED_NODE_SNAPSHOT_TYPE and ORDERED_NODE_SNAPSHOT_TYPE. } return m_list.item(index); } /** * Check if the specified type is one of the supported types. * @param type The specified type * * @return true If the specified type is supported; otherwise, returns false. */ public static boolean isValidType( short type ) { switch (type) { case ANY_TYPE: case NUMBER_TYPE: case STRING_TYPE: case BOOLEAN_TYPE: case UNORDERED_NODE_ITERATOR_TYPE: case ORDERED_NODE_ITERATOR_TYPE: case UNORDERED_NODE_SNAPSHOT_TYPE: case ORDERED_NODE_SNAPSHOT_TYPE: case ANY_UNORDERED_NODE_TYPE: case FIRST_ORDERED_NODE_TYPE: return true; default: return false; } } /** * @see org.w3c.dom.events.EventListener#handleEvent(Event) */ public void handleEvent(Event event) { if (event.getType().equals("MutationEvents")) { // invalidate the iterator m_isInvalidIteratorState = true; // deregister as a listener to reduce computational load ((EventTarget)m_contextNode).removeEventListener("MutationEvents",this,true); } } /** * Given a request type, return the equivalent string. * For diagnostic purposes. * * @return type string */ public String getTypeString(int type) { switch (type) { case ANY_TYPE: return "ANY_TYPE"; case ANY_UNORDERED_NODE_TYPE: return "ANY_UNORDERED_NODE_TYPE"; case BOOLEAN_TYPE: return "BOOLEAN"; case FIRST_ORDERED_NODE_TYPE: return "FIRST_ORDERED_NODE_TYPE"; case NUMBER_TYPE: return "NUMBER_TYPE"; case ORDERED_NODE_ITERATOR_TYPE: return "ORDERED_NODE_ITERATOR_TYPE"; case ORDERED_NODE_SNAPSHOT_TYPE: return "ORDERED_NODE_SNAPSHOT_TYPE"; case STRING_TYPE: return "STRING_TYPE"; case UNORDERED_NODE_ITERATOR_TYPE: return "UNORDERED_NODE_ITERATOR_TYPE"; case UNORDERED_NODE_SNAPSHOT_TYPE: return "UNORDERED_NODE_SNAPSHOT_TYPE"; default: return "#UNKNOWN"; } } /** * Given an XObject, determine the corresponding DOM XPath type * * @return type string */ private short getTypeFromXObject(XObject object) { switch (object.getType()) { case XObject.CLASS_BOOLEAN: return BOOLEAN_TYPE; case XObject.CLASS_NODESET: return UNORDERED_NODE_ITERATOR_TYPE; case XObject.CLASS_NUMBER: return NUMBER_TYPE; case XObject.CLASS_STRING: return STRING_TYPE; // XPath 2.0 types // case XObject.CLASS_DATE: // case XObject.CLASS_DATETIME: // case XObject.CLASS_DTDURATION: // case XObject.CLASS_GDAY: // case XObject.CLASS_GMONTH: // case XObject.CLASS_GMONTHDAY: // case XObject.CLASS_GYEAR: // case XObject.CLASS_GYEARMONTH: // case XObject.CLASS_TIME: // case XObject.CLASS_YMDURATION: return STRING_TYPE; // treat all date types as strings? case XObject.CLASS_RTREEFRAG: return UNORDERED_NODE_ITERATOR_TYPE; case XObject.CLASS_NULL: return ANY_TYPE; // throw exception ? default: return ANY_TYPE; // throw exception ? } } } 1.1 xml-xalan/java/src/org/apache/xpath/domapi/XPathNSResolverImpl.java Index: XPathNSResolverImpl.java =================================================================== /* * The Apache Software License, Version 1.1 * * * Copyright (c) 2002 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Xalan" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 1999, Lotus * Development Corporation., http://www.lotus.com. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.xpath.domapi; import org.apache.xml.utils.PrefixResolverDefault; import org.w3c.dom.Node; import org.w3c.dom.xpath.XPathNSResolver; /** * <meta name="usage" content="experimental"/> * * The class provides an implementation XPathNSResolver according * to the DOM L3 XPath API Specification, Working Draft 28, March 2002. * * * <p>The <code>XPathNSResolver</code> interface permit <code>prefix</code> * strings in the expression to be properly bound to * <code>namespaceURI</code> strings. <code>XPathEvaluator</code> can * construct an implementation of <code>XPathNSResolver</code> from a node, * or the interface may be implemented by any application.</p> * <p>See also the <a href='http://www.w3.org/TR/2002/WD-DOM-Level-3-XPath-20020328'>Document Object Model (DOM) Level 3 XPath Specification</a>.</p> * * @see org.w3c.dom.xpath.XPathNSResolver */ public class XPathNSResolverImpl extends PrefixResolverDefault implements XPathNSResolver { /** * Constructor for XPathNSResolverImpl. * @param xpathExpressionContext */ public XPathNSResolverImpl(Node xpathExpressionContext) { super(xpathExpressionContext); } /** * @see org.w3c.dom.xpath.XPathNSResolver#lookupNamespaceURI(String) */ public String lookupNamespaceURI(String prefix) { return super.getNamespaceForPrefix(prefix); } } 1.1 xml-xalan/java/src/org/apache/xpath/domapi/XPathEvaluatorImpl.java Index: XPathEvaluatorImpl.java =================================================================== /* * The Apache Software License, Version 1.1 * * * Copyright (c) 2002 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Xalan" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation and was * originally based on software copyright (c) 1999, Lotus * Development Corporation., http://www.lotus.com. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */ package org.apache.xpath.domapi; import javax.xml.transform.TransformerException; import org.apache.xalan.res.XSLMessages; import org.apache.xml.utils.PrefixResolver; import org.apache.xpath.XPath; import org.apache.xpath.res.XPATHErrorResources; import org.w3c.dom.DOMException; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.xpath.XPathEvaluator; import org.w3c.dom.xpath.XPathException; import org.w3c.dom.xpath.XPathExpression; import org.w3c.dom.xpath.XPathNSResolver; import org.w3c.dom.xpath.XPathResult; /** * <meta name="usage" content="experimental"/> * * The class provides an implementation of XPathEvaluator according * to the DOM L3 XPath Specification, Working Draft 28, March 2002. * * <p>See also the <a href='http://www.w3.org/TR/2002/WD-DOM-Level-3-XPath-20020328'>Document Object Model (DOM) Level 3 XPath Specification</a>.</p> * * </p>The evaluation of XPath expressions is provided by * <code>XPathEvaluator</code>, which will provide evaluation of XPath 1.0 * expressions with no specialized extension functions or variables. It is * expected that the <code>XPathEvaluator</code> interface will be * implemented on the same object which implements the <code>Document</code> * interface in an implementation which supports the XPath DOM module. * <code>XPathEvaluator</code> implementations may be available from other * sources that may provide support for special extension functions or * variables which are not defined in this specification.</p> * * @see org.w3c.dom.xpath.XPathEvaluator * */ public class XPathEvaluatorImpl implements XPathEvaluator { /** * This prefix resolver is created whenever null is passed to the * evaluate method. Its purpose is to satisfy the DOM L3 XPath API * requirement that if a null prefix resolver is used, an exception * should only be thrown when an attempt is made to resolve a prefix. */ class DummyPrefixResolver implements PrefixResolver { /** * Constructor for DummyPrefixResolver. */ public DummyPrefixResolver() {} /** * @exception DOMException * NAMESPACE_ERR: Always throws this exceptionn * * @see org.apache.xml.utils.PrefixResolver#getNamespaceForPrefix(String, Node) */ public String getNamespaceForPrefix(String prefix, Node context) { String fmsg = XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_RESOLVER, null); throw new DOMException(DOMException.NAMESPACE_ERR, fmsg); // Unable to resolve prefix with null prefix resolver. } /** * @exception DOMException * NAMESPACE_ERR: Always throws this exceptionn * * @see org.apache.xml.utils.PrefixResolver#getNamespaceForPrefix(String) */ public String getNamespaceForPrefix(String prefix) { return getNamespaceForPrefix(prefix,null); } /** * @see org.apache.xml.utils.PrefixResolver#handlesNullPrefixes() */ public boolean handlesNullPrefixes() { return false; } /** * @see org.apache.xml.utils.PrefixResolver#getBaseIdentifier() */ public String getBaseIdentifier() { return null; } } /** * The document to be searched to parallel the case where the XPathEvaluator * is obtained by casting a Document. */ private Document m_doc = null; /** * Constructor for XPathEvaluatorImpl. */ public XPathEvaluatorImpl() { super(); } /** * Constructor for XPathEvaluatorImpl. * * @param doc The document to be searched, to parallel the case where'' * the XPathEvaluator is obtained by casting the document. */ public XPathEvaluatorImpl(Document doc) { m_doc = doc; } /** * Creates a parsed XPath expression with resolved namespaces. This is * useful when an expression will be reused in an application since it * makes it possible to compile the expression string into a more * efficient internal form and preresolve all namespace prefixes which * occur within the expression. * * @param expression The XPath expression string to be parsed. * @param resolver The <code>resolver</code> permits translation of * prefixes within the XPath expression into appropriate namespace URIs * . If this is specified as <code>null</code>, any namespace prefix * within the expression will result in <code>DOMException</code> * being thrown with the code <code>NAMESPACE_ERR</code>. * @return The compiled form of the XPath expression. * @exception XPathException * INVALID_EXPRESSION_ERR: Raised if the expression is not legal * according to the rules of the <code>XPathEvaluator</code>i * @exception DOMException * NAMESPACE_ERR: Raised if the expression contains namespace prefixes * which cannot be resolved by the specified * <code>XPathNSResolver</code>. * * @see org.w3c.dom.xpath.XPathEvaluator#createExpression(String, XPathNSResolver) */ public XPathExpression createExpression( String expression, XPathNSResolver resolver) throws XPathException, DOMException { try { // If the resolver is null, create a dummy prefix resolver XPath xpath = new XPath(expression,null, ((null == resolver) ? new DummyPrefixResolver() : ((PrefixResolver)resolver)), XPath.SELECT); return new XPathExpressionImpl(xpath, m_doc); } catch (TransformerException e) { throw new DOMException(XPathException.INVALID_EXPRESSION_ERR,e.getMessageAndLocation()); } } /** * Adapts any DOM node to resolve namespaces so that an XPath expression * can be easily evaluated relative to the context of the node where it * appeared within the document. This adapter works like the DOM Level 3 * method <code>lookupNamespaceURI</code> on nodes in resolving the * namespaceURI from a given prefix using the current information available * in the node's hierarchy at the time lookupNamespaceURI is called, also * correctly resolving the implicit xml prefix. * * @param nodeResolver The node to be used as a context for namespace * resolution. * @return <code>XPathNSResolver</code> which resolves namespaces with * respect to the definitions in scope for a specified node. * * @see org.w3c.dom.xpath.XPathEvaluator#createNSResolver(Node) */ public XPathNSResolver createNSResolver(Node nodeResolver) { return new XPathNSResolverImpl((nodeResolver.getNodeType() == Node.DOCUMENT_NODE) ? ((Document) nodeResolver).getDocumentElement() : nodeResolver); } /** * Evaluates an XPath expression string and returns a result of the * specified type if possible. * * @param expression The XPath expression string to be parsed and * evaluated. * @param contextNode The <code>context</code> is context node for the * evaluation of this XPath expression. If the XPathEvaluator was * obtained by casting the <code>Document</code> then this must be * owned by the same document and must be a <code>Document</code>, * <code>Element</code>, <code>Attribute</code>, <code>Text</code>, * <code>CDATASection</code>, <code>Comment</code>, * <code>ProcessingInstruction</code>, or <code>XPathNamespace</code> * node. If the context node is a <code>Text</code> or a * <code>CDATASection</code>, then the context is interpreted as the * whole logical text node as seen by XPath, unless the node is empty * in which case it may not serve as the XPath context. * @param resolver The <code>resolver</code> permits translation of * prefixes within the XPath expression into appropriate namespace URIs * . If this is specified as <code>null</code>, any namespace prefix * within the expression will result in <code>DOMException</code> * being thrown with the code <code>NAMESPACE_ERR</code>. * @param type If a specific <code>type</code> is specified, then the * result will be coerced to return the specified type relying on * XPath type conversions and fail if the desired coercion is not * possible. This must be one of the type codes of * <code>XPathResult</code>. * @param result The <code>result</code> specifies a specific result * object which may be reused and returned by this method. If this is * specified as <code>null</code>or the implementation does not reuse * the specified result, a new result object will be constructed and * returned.For XPath 1.0 results, this object will be of type * <code>XPathResult</code>. * @return The result of the evaluation of the XPath expression.For XPath * 1.0 results, this object will be of type <code>XPathResult</code>. * @exception XPathException * INVALID_EXPRESSION_ERR: Raised if the expression is not legal * according to the rules of the <code>XPathEvaluator</code>i * <br>TYPE_ERR: Raised if the result cannot be converted to return the * specified type. * @exception DOMException * NAMESPACE_ERR: Raised if the expression contains namespace prefixes * which cannot be resolved by the specified * <code>XPathNSResolver</code>. * <br>WRONG_DOCUMENT_ERR: The Node is from a document that is not * supported by this XPathEvaluator. * <br>NOT_SUPPORTED_ERR: The Node is not a type permitted as an XPath * context node. * * @see org.w3c.dom.xpath.XPathEvaluator#evaluate(String, Node, XPathNSResolver, short, XPathResult) */ public Object evaluate( String expression, Node contextNode, XPathNSResolver resolver, short type, Object result) throws XPathException, DOMException { XPathExpression xpathExpression = createExpression(expression, resolver); return xpathExpression.evaluate(contextNode, type, result); } } 1.17 +36 -0 xml-xalan/java/src/org/apache/xpath/res/XPATHErrorResources.java Index: XPATHErrorResources.java =================================================================== RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/res/XPATHErrorResources.java,v retrieving revision 1.16 retrieving revision 1.17 diff -u -r1.16 -r1.17 --- XPATHErrorResources.java 10 Jul 2002 16:06:32 -0000 1.16 +++ XPATHErrorResources.java 20 Sep 2002 13:48:48 -0000 1.17 @@ -522,9 +522,45 @@ public static final int ER_ARG_PREFIX_INVALID = 102; +/** Field ER_CANT_CONVERT_TO_BOOLEAN */ + public static final int ER_CANT_CONVERT_TO_BOOLEAN = 103; + + +/** Field ER_CANT_CONVERT_TO_SINGLENODE */ + public static final int ER_CANT_CONVERT_TO_SINGLENODE = 104; +/** Field ER_CANT_GET_SNAPSHOT_LENGTH */ + public static final int ER_CANT_GET_SNAPSHOT_LENGTH = 105; + +/** Field ER_NON_ITERATOR_TYPE */ + public static final int ER_NON_ITERATOR_TYPE = 106; +/** Field ER_DOC_MUTATED */ + public static final int ER_DOC_MUTATED = 107; + +/** Field ER_INVALID_XPATH_TYPE */ + public static final int ER_INVALID_XPATH_TYPE = 108; + +/** Field ER_EMPTY_XPATH_RESULT */ + public static final int ER_EMPTY_XPATH_RESULT = 109; +/** Field ER_INCOMPATIBLE_TYPES */ + public static final int ER_INCOMPATIBLE_TYPES = 110; + +/** Field ER_NULL_RESOLVER */ + public static final int ER_NULL_RESOLVER = 111; + +/** Field ER_CANT_CONVERT_TO_STRING */ + public static final int ER_CANT_CONVERT_TO_STRING = 112; + +/** Field ER_NON_SNAPSHOT_TYPE */ + public static final int ER_NON_SNAPSHOT_TYPE = 113; + +/** Field ER_WRONG_DOCUMENT */ + public static final int ER_WRONG_DOCUMENT = 114; + +/** Field ER_WRONG_NODETYPE */ + public static final int ER_WRONG_NODETYPE = 115; // Warnings... 1.8 +29 -1 xml-xalan/java/src/org/apache/xpath/res/XPATHErrorResources.properties Index: XPATHErrorResources.properties =================================================================== RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/res/XPATHErrorResources.properties,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- XPATHErrorResources.properties 10 Jul 2002 16:06:32 -0000 1.7 +++ XPATHErrorResources.properties 20 Sep 2002 13:48:48 -0000 1.8 @@ -210,7 +210,35 @@ ER0101= Localname in QNAME should be a valid NCName # ER_ARG_PREFIX_INVALID ER0102=Prefix in QNAME should be a valid NCName - +# ER_CANT_CONVERT_TO_BOOLEAN +ER0103=Can not convert {0} to a boolean. +# ER_CANT_CONVERT_TO_SINGLENODE. +# Note to translators: Do not translate ANY_UNORDERED_NODE_TYPE and FIRST_ORDERED_NODE_TYPE. +ER0104=Can not convert {0} to a single node. This getter applies to types ANY_UNORDERED_NODE_TYPE and FIRST_ORDERED_NODE_TYPE. +# ER_CANT_GET_SNAPSHOT_LENGTH +# Note to translators: Do not translate UNORDERED_NODE_SNAPSHOT_TYPE and ORDERED_NODE_SNAPSHOT_TYPE. +ER0105=Can not get snapshot length on type: {0}. This getter applies to types UNORDERED_NODE_SNAPSHOT_TYPE and ORDERED_NODE_SNAPSHOT_TYPE. +# ER_NON_ITERATOR_TYPE +ER0106=Can not iterate over non iterator type: {0} +# ER_DOC_MUTATED +ER0107=Document mutated since result was returned. Iterator is invalid. +# ER_INVALID_XPATH_TYPE +ER0108=Invalid XPath type argument: {0} +# ER_EMPTY_XPATH_RESULT +ER0109=Empty XPath result object +# ER_INCOMPATIBLE_TYPES +ER0110=The returned type: {0} can not be coerced into the specified type: {1} +# ER_NULL_RESOLVER +ER0111=Unable to resolve prefix with null prefix resolver. +# ER_CANT_CONVERT_TO_STRING +ER0112=Can not convert {0} to a string. +# ER_NON_SNAPSHOT_TYPE +# Note to translators: Do not translate UNORDERED_NODE_SNAPSHOT_TYPE and ORDERED_NODE_SNAPSHOT_TYPE. +ER0113=Can call snapshotItem on type: {0}. This method applies to types UNORDERED_NODE_SNAPSHOT_TYPE and ORDERED_NODE_SNAPSHOT_TYPE. +# ER_WRONG_DOCUMENT +ER0114=Context node does not belong to the document that is bound to this XPathEvaluator. +# ER_WRONG_NODETYPE +ER0115=The context node type is node supported. # WG_LOCALE_NAME_NOT_HANDLED WR0001=locale name in the format-number function not yet handled!
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]