001: /*
002: * Copyright 2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.xml.xpath;
018:
019: import java.util.ArrayList;
020: import java.util.List;
021: import java.util.Map;
022:
023: import org.jaxen.JaxenException;
024: import org.jaxen.SimpleNamespaceContext;
025: import org.jaxen.XPath;
026: import org.jaxen.dom.DOMXPath;
027: import org.w3c.dom.DOMException;
028: import org.w3c.dom.Node;
029:
030: /**
031: * Jaxen-specific factory for creating <code>XPathExpression</code>s.
032: *
033: * @author Arjen Poutsma
034: * @see #createXPathExpression(String)
035: * @since 1.0.0
036: */
037: abstract class JaxenXPathExpressionFactory {
038:
039: /**
040: * Creates a Jaxen <code>XPathExpression</code> from the given string expression.
041: *
042: * @param expression the XPath expression
043: * @return the compiled <code>XPathExpression</code>
044: * @throws XPathParseException when the given expression cannot be parsed
045: */
046: static XPathExpression createXPathExpression(String expression) {
047: try {
048: XPath xpath = new DOMXPath(expression);
049: return new JaxenXpathExpression(xpath);
050: } catch (JaxenException ex) {
051: throw new org.springframework.xml.xpath.XPathParseException(
052: "Could not compile [" + expression
053: + "] to a XPathExpression: "
054: + ex.getMessage(), ex);
055: }
056: }
057:
058: /**
059: * Creates a Jaxen <code>XPathExpression</code> from the given string expression and prefixes.
060: *
061: * @param expression the XPath expression
062: * @param namespaces the namespaces
063: * @return the compiled <code>XPathExpression</code>
064: * @throws XPathParseException when the given expression cannot be parsed
065: */
066: public static XPathExpression createXPathExpression(
067: String expression, Map namespaces) {
068: try {
069: XPath xpath = new DOMXPath(expression);
070: xpath.setNamespaceContext(new SimpleNamespaceContext(
071: namespaces));
072: return new JaxenXpathExpression(xpath);
073: } catch (JaxenException ex) {
074: throw new org.springframework.xml.xpath.XPathParseException(
075: "Could not compile [" + expression
076: + "] to a XPathExpression: "
077: + ex.getMessage(), ex);
078: }
079: }
080:
081: /** Jaxen implementation of the <code>XPathExpression</code> interface. */
082: private static class JaxenXpathExpression implements
083: XPathExpression {
084:
085: private XPath xpath;
086:
087: private JaxenXpathExpression(XPath xpath) {
088: this .xpath = xpath;
089: }
090:
091: public Node evaluateAsNode(Node node) {
092: try {
093: return (Node) xpath.selectSingleNode(node);
094: } catch (JaxenException ex) {
095: throw new XPathException(
096: "Could not evaluate XPath expression [" + xpath
097: + "] :" + ex.getMessage(), ex);
098: }
099: }
100:
101: public boolean evaluateAsBoolean(Node node) {
102: try {
103: return xpath.booleanValueOf(node);
104: } catch (JaxenException ex) {
105: throw new XPathException(
106: "Could not evaluate XPath expression [" + xpath
107: + "] :" + ex.getMessage(), ex);
108: }
109: }
110:
111: public double evaluateAsNumber(Node node) {
112: try {
113: return xpath.numberValueOf(node).doubleValue();
114: } catch (JaxenException ex) {
115: throw new XPathException(
116: "Could not evaluate XPath expression [" + xpath
117: + "] :" + ex.getMessage(), ex);
118: }
119: }
120:
121: public String evaluateAsString(Node node) {
122: try {
123: return xpath.stringValueOf(node);
124: } catch (JaxenException ex) {
125: throw new XPathException(
126: "Could not evaluate XPath expression [" + xpath
127: + "] :" + ex.getMessage(), ex);
128: }
129: }
130:
131: public List evaluateAsNodeList(Node node) {
132: try {
133: return xpath.selectNodes(node);
134: } catch (JaxenException ex) {
135: throw new XPathException(
136: "Could not evaluate XPath expression [" + xpath
137: + "] :" + ex.getMessage(), ex);
138: }
139: }
140:
141: public Object evaluateAsObject(Node context,
142: NodeMapper nodeMapper) throws XPathException {
143: try {
144: Node result = (Node) xpath.selectSingleNode(context);
145: if (result != null) {
146: try {
147: return nodeMapper.mapNode(result, 0);
148: } catch (DOMException ex) {
149: throw new XPathException(
150: "Mapping resulted in DOMException", ex);
151: }
152: } else {
153: return null;
154: }
155: } catch (JaxenException ex) {
156: throw new XPathException(
157: "Could not evaluate XPath expression [" + xpath
158: + "] :" + ex.getMessage(), ex);
159: }
160: }
161:
162: public List evaluate(Node context, NodeMapper nodeMapper)
163: throws XPathException {
164: try {
165: List nodes = xpath.selectNodes(context);
166: List results = new ArrayList(nodes.size());
167: for (int i = 0; i < nodes.size(); i++) {
168: Node node = (Node) nodes.get(i);
169: try {
170: results.add(nodeMapper.mapNode(node, i));
171: } catch (DOMException ex) {
172: throw new XPathException(
173: "Mapping resulted in DOMException", ex);
174: }
175: }
176: return results;
177: } catch (JaxenException ex) {
178: throw new XPathException(
179: "Could not evaluate XPath expression [" + xpath
180: + "] :" + ex.getMessage(), ex);
181: }
182: }
183: }
184: }
|