KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > excalibur > xml > xpath > Saxon7ProcessorImpl


1 /*
2  * Copyright 2002-2004 The Apache Software Foundation
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12  * implied.
13  *
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17 package org.apache.excalibur.xml.xpath;
18
19 import org.apache.avalon.framework.thread.ThreadSafe;
20 import org.apache.avalon.framework.component.Component;
21
22 import org.w3c.dom.Node JavaDoc;
23 import org.w3c.dom.NodeList JavaDoc;
24 import net.sf.saxon.om.NodeInfo;
25 import net.sf.saxon.om.SequenceIterator;
26 import net.sf.saxon.om.Item;
27 import net.sf.saxon.xpath.XPathException;
28 import net.sf.saxon.xpath.StandaloneContext;
29 import net.sf.saxon.TransformerFactoryImpl;
30 import net.sf.saxon.expr.Expression;
31 import net.sf.saxon.expr.XPathContext;
32 import net.sf.saxon.expr.ExpressionTool;
33 import net.sf.saxon.tinytree.TinyBuilder;
34 import net.sf.saxon.value.Type;
35 import net.sf.saxon.value.BooleanValue;
36 import net.sf.saxon.value.DoubleValue;
37
38 import javax.xml.transform.TransformerFactory JavaDoc;
39 import javax.xml.transform.dom.DOMSource JavaDoc;
40 import java.util.ArrayList JavaDoc;
41
42 /**
43  * This class defines the implementation of the {@link XPathProcessor}
44  * component. This implementation depends on Saxon 7.X XSLT processor.
45  * This implementation was tested with Saxon 7.5 release.
46  *
47  * To configure it, add the following lines in the
48  * <file>cocoon.xconf</file> file:
49  *
50  * <pre>
51  * &lt;xslt-processor class="org.apache.cocoon.components.xpath.Saxon7ProcessorImpl"&gt;
52  * &lt;/xslt-processor&gt;
53  * </pre>
54  *
55  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
56  * @version CVS $Id: Saxon7ProcessorImpl.java,v 1.4 2004/02/28 11:47:15 cziegeler Exp $
57  */

58 public class Saxon7ProcessorImpl
59         extends AbstractProcessorImpl
60         implements XPathProcessor, Component, ThreadSafe
61 {
62     private static final TransformerFactory JavaDoc factory = new TransformerFactoryImpl();
63
64     /**
65      * Evaluate XPath expression within a context.
66      *
67      * @param contextNode The context node.
68      * @param str A valid XPath string.
69      * @param resolver a PrefixResolver, used for resolving namespace prefixes
70      * @return expression result as boolean.
71      */

72     public boolean evaluateAsBoolean(Node JavaDoc contextNode, String JavaDoc str, PrefixResolver resolver)
73     {
74         try
75         {
76             Item item = evaluateSingle(contextNode, str, resolver);
77             if (item == null)
78             {
79                 return false;
80             }
81
82             if (item.getItemType() == Type.BOOLEAN)
83             {
84                 return ((BooleanValue)item).getValue();
85             }
86
87             return Boolean.valueOf(item.getStringValue()).booleanValue();
88         }
89         catch (final Exception JavaDoc e)
90         {
91             if (getLogger().isDebugEnabled()) {
92                 getLogger().debug("Failed to evaluate '" + str + "'", e);
93             }
94
95             // ignore it
96
return false;
97         }
98     }
99
100     /**
101      * Evaluate XPath expression within a context.
102      *
103      * @param contextNode The context node.
104      * @param str A valid XPath string.
105      * @param resolver a PrefixResolver, used for resolving namespace prefixes
106      * @return expression result as number.
107      */

108     public Number JavaDoc evaluateAsNumber(Node JavaDoc contextNode, String JavaDoc str, PrefixResolver resolver)
109     {
110         try
111         {
112             Item item = evaluateSingle(contextNode, str, resolver);
113             if (item == null)
114             {
115                 return null;
116             }
117
118             if (item.getItemType() == Type.NUMBER)
119             {
120                 return new Double JavaDoc(((DoubleValue)item).getValue());
121             }
122
123             return Double.valueOf(item.getStringValue());
124         }
125         catch (final Exception JavaDoc e)
126         {
127             if (getLogger().isDebugEnabled()) {
128                 getLogger().debug("Failed to evaluate '" + str + "'", e);
129             }
130
131             // ignore it
132
return null;
133         }
134     }
135
136     /**
137      * Evaluate XPath expression within a context.
138      *
139      * @param contextNode The context node.
140      * @param str A valid XPath string.
141      * @param resolver a PrefixResolver, used for resolving namespace prefixes
142      * @return expression result as string.
143      */

144     public String JavaDoc evaluateAsString(Node JavaDoc contextNode, String JavaDoc str, PrefixResolver resolver) {
145         try
146         {
147             Item item = evaluateSingle(contextNode, str, resolver);
148             if (item == null)
149             {
150                 return null;
151             }
152
153             return item.getStringValue();
154         }
155         catch (final Exception JavaDoc e)
156         {
157             if (getLogger().isDebugEnabled()) {
158                 getLogger().debug("Failed to evaluate '" + str + "'", e);
159             }
160
161             // ignore it
162
return null;
163         }
164     }
165
166     public Node JavaDoc selectSingleNode(Node JavaDoc contextNode, String JavaDoc str, PrefixResolver resolver)
167     {
168         try
169         {
170             Item item = evaluateSingle(contextNode, str, resolver);
171
172             return (Node JavaDoc)item;
173         }
174         catch (final Exception JavaDoc e)
175         {
176             if (getLogger().isDebugEnabled()) {
177                 getLogger().debug("Failed to evaluate '" + str + "'", e);
178             }
179
180             // ignore it
181
return null;
182         }
183     }
184
185     public NodeList JavaDoc selectNodeList(Node JavaDoc contextNode, String JavaDoc str, PrefixResolver resolver)
186     {
187         try
188         {
189             SequenceIterator iterator = evaluate(contextNode, str, resolver);
190             ArrayList JavaDoc nodes = new ArrayList JavaDoc();
191             while (iterator.hasNext())
192             {
193                 Node JavaDoc node = (Node JavaDoc)iterator.current();
194                 nodes.add(node);
195             }
196
197             return new NodeListImpl((Node JavaDoc[])nodes.toArray());
198         } catch (final Exception JavaDoc e) {
199             if (getLogger().isDebugEnabled()) {
200                 getLogger().debug("Failed to evaluate '" + str + "'", e);
201             }
202
203             // ignore it
204
return null;
205         }
206     }
207
208     private Item evaluateSingle(Node JavaDoc contextNode, String JavaDoc str, PrefixResolver resolver)
209     {
210         try
211         {
212             SequenceIterator iterator = evaluate(contextNode, str, resolver);
213             if (iterator == null)
214             {
215                 return null;
216             }
217
218             return iterator.current();
219         }
220         catch (final Exception JavaDoc e)
221         {
222             if (getLogger().isDebugEnabled()) {
223                 getLogger().debug("Failed to evaluate '" + str + "'", e);
224             }
225
226             // ignore it
227
return null;
228         }
229     }
230
231     private SequenceIterator evaluate(Node JavaDoc contextNode, String JavaDoc str, PrefixResolver resolver)
232     {
233         try
234         {
235             if (!(contextNode instanceof NodeInfo))
236             {
237                 getLogger().debug("Input tree is not SAXON TinyTree, converting");
238                 DOMSource JavaDoc source = new DOMSource JavaDoc(contextNode);
239                 TinyBuilder result = new TinyBuilder();
240                 factory.newTransformer().transform(source, result);
241                 contextNode = (Node JavaDoc)result.getCurrentDocument();
242             }
243
244             Expression expression = ExpressionTool.make(
245                     str, new Saxon7Context((NodeInfo)contextNode, resolver));
246             XPathContext context = new XPathContext((NodeInfo)contextNode);
247             return expression.iterate(context);
248         }
249         catch (final Exception JavaDoc e)
250         {
251             if (getLogger().isDebugEnabled()) {
252                 getLogger().debug("Failed to evaluate '" + str + "'", e);
253             }
254
255             // ignore it
256
return null;
257         }
258     }
259
260
261     private class Saxon7Context extends StandaloneContext
262     {
263         private final PrefixResolver resolver;
264
265         public Saxon7Context(NodeInfo node, PrefixResolver resolver)
266         {
267             super(node);
268             this.resolver = resolver;
269         }
270
271         public String JavaDoc getURIForPrefix(String JavaDoc prefix) throws XPathException
272         {
273             return resolver.prefixToNamespace(prefix);
274         }
275     }
276 }
277
Popular Tags