KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > webharvest > runtime > processors > XQueryProcessor


1 /* Copyright (c) 2006-2007, Vladimir Nikic
2     All rights reserved.
3
4     Redistribution and use of this software in source and binary forms,
5     with or without modification, are permitted provided that the following
6     conditions are met:
7
8     * Redistributions of source code must retain the above
9       copyright notice, this list of conditions and the
10       following disclaimer.
11
12     * Redistributions in binary form must reproduce the above
13       copyright notice, this list of conditions and the
14       following disclaimer in the documentation and/or other
15       materials provided with the distribution.
16
17     * The name of Web-Harvest may not be used to endorse or promote
18       products derived from this software without specific prior
19       written permission.
20
21     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24     ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25     LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31     POSSIBILITY OF SUCH DAMAGE.
32
33     You can contact Vladimir Nikic by sending e-mail to
34     nikic_vladimir@yahoo.com. Please include the word "Web-Harvest" in the
35     subject line.
36 */

37 package org.webharvest.runtime.processors;
38
39 import net.sf.saxon.Configuration;
40 import net.sf.saxon.om.Item;
41 import net.sf.saxon.om.SequenceIterator;
42 import net.sf.saxon.query.*;
43 import net.sf.saxon.trans.XPathException;
44 import org.webharvest.definition.XQueryDef;
45 import org.webharvest.definition.XQueryExternalParamDef;
46 import org.webharvest.definition.BaseElementDef;
47 import org.webharvest.exception.ScraperXQueryException;
48 import org.webharvest.runtime.Scraper;
49 import org.webharvest.runtime.ScraperContext;
50 import org.webharvest.runtime.variables.*;
51 import org.webharvest.utils.CommonUtil;
52
53 import javax.xml.transform.stream.StreamSource JavaDoc;
54 import java.io.StringReader JavaDoc;
55 import java.util.*;
56
57 /**
58  * XQuery processor.
59  */

60 public class XQueryProcessor extends BaseProcessor {
61
62     public static Set ALLOWED_PARAM_TYPES = new TreeSet();
63     public static String JavaDoc DEFAULT_PARAM_TYPE = "node()";
64
65     // initialize set of allowed parameter types
66
static {
67         ALLOWED_PARAM_TYPES.add("node()");
68         ALLOWED_PARAM_TYPES.add("node()*");
69         ALLOWED_PARAM_TYPES.add("integer");
70         ALLOWED_PARAM_TYPES.add("integer*");
71         ALLOWED_PARAM_TYPES.add("long");
72         ALLOWED_PARAM_TYPES.add("long*");
73         ALLOWED_PARAM_TYPES.add("float");
74         ALLOWED_PARAM_TYPES.add("float*");
75         ALLOWED_PARAM_TYPES.add("double");
76         ALLOWED_PARAM_TYPES.add("double*");
77         ALLOWED_PARAM_TYPES.add("boolean");
78         ALLOWED_PARAM_TYPES.add("boolean*");
79         ALLOWED_PARAM_TYPES.add("string");
80         ALLOWED_PARAM_TYPES.add("string*");
81     }
82
83     private XQueryDef xqueryDef;
84
85     public XQueryProcessor(XQueryDef xqueryDef) {
86         super(xqueryDef);
87         this.xqueryDef = xqueryDef;
88     }
89
90     public IVariable execute(Scraper scraper, ScraperContext context) {
91         BaseElementDef xqueryElementDef = xqueryDef.getXqDef();
92         IVariable xq = getBodyTextContent(xqueryElementDef, scraper, context);
93         debug(xqueryElementDef, scraper, xq);
94
95         String JavaDoc xqExpression = xq.toString().trim();
96         XQueryExternalParamDef[] externalParamDefs = xqueryDef.getExternalParamDefs();
97
98         final Configuration config = new Configuration();
99         final StaticQueryContext sqc = new StaticQueryContext(config);
100
101         try {
102             final XQueryExpression exp = sqc.compileQuery(xqExpression);
103             final DynamicQueryContext dynamicContext = new DynamicQueryContext(config);
104
105             // define external parameters
106
for (int i = 0; i < externalParamDefs.length; i++) {
107                 XQueryExternalParamDef externalParamDef = externalParamDefs[i];
108                 String JavaDoc externalParamType = externalParamDefs[i].getType();
109                 if (externalParamType == null) {
110                     externalParamType = DEFAULT_PARAM_TYPE;
111                 }
112
113                 // check if param type is one of allowed
114
if ( !ALLOWED_PARAM_TYPES.contains(externalParamType) ) {
115                     throw new ScraperXQueryException("Type " + externalParamType + " is not allowed. Use one of " + ALLOWED_PARAM_TYPES.toString());
116                 }
117
118                 if ( externalParamType.endsWith("*") ) {
119                     ListVariable listVar = (ListVariable) getBodyListContent(externalParamDef, scraper, context);
120                     debug(externalParamDef, scraper, listVar);
121                     
122                     Iterator it = listVar.toList().iterator();
123                     List paramList = new ArrayList();
124                     while (it.hasNext()) {
125                         IVariable currVar = (IVariable) it.next();
126                         paramList.add( castSimpleValue(externalParamType, currVar, sqc) );
127                     }
128
129                     dynamicContext.setParameter(externalParamDef.getName(), paramList);
130                 } else {
131                     IVariable var = getBodyTextContent(externalParamDef, scraper, context);
132
133                     debug(externalParamDef, scraper, var);
134                     
135                     Object JavaDoc value = castSimpleValue(externalParamType, var, sqc);
136                     dynamicContext.setParameter(externalParamDef.getName(), value);
137                 }
138             }
139
140             final SequenceIterator iter = exp.iterator(dynamicContext);
141             
142             ListVariable listVariable = new ListVariable();
143             while (true) {
144                 Item item = iter.next();
145                 if (item == null) {
146                     break;
147                 }
148                 
149                 String JavaDoc value = CommonUtil.serializeItem(item, config);
150                 listVariable.addVariable( new NodeVariable(value) );
151             }
152
153             return listVariable;
154         } catch (XPathException e) {
155             throw new ScraperXQueryException("Error executing XQuery expression (XQuery = [" + xqExpression + "])!", e);
156         }
157     }
158
159     /**
160      * For the specified type, value and static query context, returns proper Java typed value.
161      * @param type
162      * @param value
163      * @param sqc
164      * @return
165      * @throws XPathException
166      */

167     private Object JavaDoc castSimpleValue(String JavaDoc type, IVariable value, StaticQueryContext sqc) throws XPathException {
168         type = type.toLowerCase();
169
170         if ( type.startsWith("node()") ) {
171             StringReader JavaDoc reader = new StringReader JavaDoc(value.toString() );
172             return sqc.buildDocument(new StreamSource JavaDoc(reader));
173         } else if ( type.startsWith("integer") ) {
174             return new Integer JavaDoc( value.toString() );
175         } else if ( type.startsWith("long") ) {
176             return new Long JavaDoc( value.toString() );
177         } else if ( type.startsWith("float") ) {
178             return new Float JavaDoc( value.toString() );
179         } else if ( type.startsWith("double") ) {
180             return new Double JavaDoc( value.toString() );
181         } else if ( type.startsWith("boolean") ) {
182             return CommonUtil.isBooleanTrue(value.toString()) ? Boolean.TRUE : Boolean.FALSE;
183         } else {
184             return value.toString();
185         }
186     }
187
188 }
Popular Tags