001: // You can redistribute this software and/or modify it under the terms of
002: // the Infozone Software License version 2 published by the Infozone Group
003: // (http://www.infozone-group.org).
004: //
005: // Copyright (C) @year@ by The Infozone Group. All rights reserved.
006: //
007: // $Id: XPathQueryImpl.java,v 1.1 2002/05/10 08:59:12 per_nyfelt Exp $
008:
009: package org.infozone.tools.xml.queries.xalan;
010:
011: import org.w3c.dom.Document;
012: import org.w3c.dom.Node;
013: import org.w3c.dom.traversal.NodeFilter;
014:
015: import org.infozone.tools.xml.queries.XObject;
016: import org.infozone.tools.xml.queries.XPathQuery;
017:
018: import org.apache.xalan.xpath.*;
019: import org.apache.xalan.xpath.xml.PrefixResolver;
020: import org.apache.xalan.xpath.xml.PrefixResolverDefault;
021: import org.apache.xalan.xpath.xml.XMLParserLiaisonDefault;
022:
023: /**
024: * @version $Revision: 1.1 $ $Date: 2002/05/10 08:59:12 $
025: * @author <a href="http://www.softwarebuero.de">SMB</a>
026: */
027: public final class XPathQueryImpl implements XPathQuery {
028:
029: //
030: // Data
031: //
032:
033: private String qstring;
034:
035: private Node rootNode;
036:
037: private Node namespace;
038:
039: private NodeFilter filter;
040:
041: private boolean hasChanged = true;
042:
043: private XPathSupport xpathSupport;
044:
045: private XPathProcessorImpl parser;
046:
047: private XPath xpath;
048:
049: private PrefixResolver prefixResolver;
050:
051: public XPathQueryImpl() {
052: // Since we don't have a XML Parser involved here, install some
053: // default support for things like namespaces, etc.
054: xpathSupport = new XMLParserLiaisonDefault();
055:
056: // Create a XPath parser.
057: parser = new org.apache.xalan.xpath.XPathProcessorImpl(
058: xpathSupport);
059:
060: // Create the XPath object.
061: xpath = new XPath();
062: }
063:
064: public void setQString(String qstring) throws Exception {
065: this .qstring = qstring;
066: this .hasChanged = true;
067: }
068:
069: public void setNamespace(Node namespace) throws Exception {
070: this .namespace = namespace;
071: this .hasChanged = true;
072: }
073:
074: public void setNodeFilter(NodeFilter filter) throws Exception {
075: this .filter = filter;
076: this .hasChanged = true;
077: }
078:
079: protected void prepare() throws Exception {
080: // Create an object to resolve namespace prefixes.
081: // XPath namespaces are resolved from the input root node's
082: // document element if it is a root node, or else the current root node.
083: prefixResolver = namespace != null ? new PrefixResolverDefault(
084: namespace) : new PrefixResolverDefault(rootNode);
085:
086: // parse the specified Query-String and build an Parse-Tree
087: parser.initXPath(xpath, qstring, prefixResolver);
088:
089: hasChanged = false;
090: }
091:
092: /**
093: * Execute the xpath.
094: *
095: * @param rootNode The node from which the query should start or null.
096: * @param nameSpace The node that resolves namespace queries or null.
097: * @param filter The node filter which is to apply while querying or null.
098: * @return The XObject insulating the query result.
099: */
100: public XObject execute(Node rootNode) throws Exception {
101: if (rootNode.getNodeType() == Node.DOCUMENT_NODE) {
102: rootNode = ((Document) rootNode).getDocumentElement();
103: }
104:
105: this .rootNode = rootNode;
106: prepare();
107:
108: // execute the XPath query on the specified root node
109: return new XObjectImpl(xpath.execute(xpathSupport, rootNode,
110: prefixResolver));
111: }
112:
113: }
|