001: /*
002: * ============================================================================
003: * GNU Lesser General Public License
004: * ============================================================================
005: *
006: * JasperReports - Free Java report-generating library.
007: * Copyright (C) 2001-2006 JasperSoft Corporation http://www.jaspersoft.com
008: *
009: * This library is free software; you can redistribute it and/or
010: * modify it under the terms of the GNU Lesser General Public
011: * License as published by the Free Software Foundation; either
012: * version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017: * Lesser General Public License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public
020: * License along with this library; if not, write to the Free Software
021: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
022: *
023: * JasperSoft Corporation
024: * 303 Second Street, Suite 450 North
025: * San Francisco, CA 94107
026: * http://www.jaspersoft.com
027: */
028: package net.sf.jasperreports.engine.util.xml;
029:
030: import java.util.ArrayList;
031: import java.util.List;
032: import java.util.Map;
033:
034: import net.sf.jasperreports.engine.JRException;
035:
036: import org.apache.commons.collections.ReferenceMap;
037: import org.jaxen.JaxenException;
038: import org.jaxen.XPath;
039: import org.jaxen.dom.DOMXPath;
040: import org.w3c.dom.Node;
041: import org.w3c.dom.NodeList;
042:
043: /**
044: * XPath executer implementation that uses <a href="http://jaxen.org/" target="_blank">Jaxen</a>.
045: *
046: * @author Lucian Chirita (lucianc@users.sourceforge.net)
047: * @version $Id: JaxenXPathExecuter.java 1756 2007-06-14 16:11:20Z lucianc $
048: */
049: public class JaxenXPathExecuter implements JRXPathExecuter {
050:
051: private final Map cachedXPaths = new ReferenceMap();//soft cache
052:
053: public JaxenXPathExecuter() {
054: }
055:
056: protected XPath getXPath(String expression) throws JRException {
057: XPath xPath = (XPath) cachedXPaths.get(expression);
058: if (xPath == null) {
059: try {
060: xPath = new DOMXPath(expression);
061: } catch (JaxenException e) {
062: throw new JRException(
063: "XPath compilation failed. Expression: "
064: + expression, e);
065: }
066: cachedXPaths.put(expression, xPath);
067: }
068: return xPath;
069: }
070:
071: public NodeList selectNodeList(Node contextNode, String expression)
072: throws JRException {
073: try {
074: XPath xpath = getXPath(expression);
075: Object object = xpath.evaluate(contextNode);
076: List nodes;
077: if (object instanceof List) {
078: nodes = (List) object;
079: } else {
080: nodes = new ArrayList();
081: nodes.add(object);
082: }
083: return new NodeListWrapper(nodes);
084: } catch (JaxenException e) {
085: throw new JRException(
086: "XPath selection failed. Expression: " + expression,
087: e);
088: }
089: }
090:
091: public Object selectObject(Node contextNode, String expression)
092: throws JRException {
093: try {
094: XPath xpath = new DOMXPath(expression);
095: Object object = xpath.evaluate(contextNode);
096: Object value;
097: if (object instanceof List) {
098: List list = (List) object;
099: if (list.isEmpty()) {
100: value = null;
101: } else {
102: value = list.get(0);
103: }
104: } else if (object instanceof Number
105: || object instanceof Boolean) {
106: value = object;
107: } else {
108: value = object.toString();
109: }
110: return value;
111: } catch (JaxenException e) {
112: throw new JRException(
113: "XPath selection failed. Expression: " + expression,
114: e);
115: }
116: }
117:
118: protected static final class NodeListWrapper implements NodeList {
119:
120: private final List nodes;
121:
122: public NodeListWrapper(List nodes) {
123: this .nodes = nodes;
124: }
125:
126: public int getLength() {
127: return nodes.size();
128: }
129:
130: public Node item(int index) {
131: return (Node) nodes.get(index);
132: }
133:
134: }
135:
136: }
|