1 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 ; 54 import java.io.StringReader ; 55 import java.util.*; 56 57 60 public class XQueryProcessor extends BaseProcessor { 61 62 public static Set ALLOWED_PARAM_TYPES = new TreeSet(); 63 public static String DEFAULT_PARAM_TYPE = "node()"; 64 65 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 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 for (int i = 0; i < externalParamDefs.length; i++) { 107 XQueryExternalParamDef externalParamDef = externalParamDefs[i]; 108 String externalParamType = externalParamDefs[i].getType(); 109 if (externalParamType == null) { 110 externalParamType = DEFAULT_PARAM_TYPE; 111 } 112 113 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 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 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 167 private Object castSimpleValue(String type, IVariable value, StaticQueryContext sqc) throws XPathException { 168 type = type.toLowerCase(); 169 170 if ( type.startsWith("node()") ) { 171 StringReader reader = new StringReader (value.toString() ); 172 return sqc.buildDocument(new StreamSource (reader)); 173 } else if ( type.startsWith("integer") ) { 174 return new Integer ( value.toString() ); 175 } else if ( type.startsWith("long") ) { 176 return new Long ( value.toString() ); 177 } else if ( type.startsWith("float") ) { 178 return new Float ( value.toString() ); 179 } else if ( type.startsWith("double") ) { 180 return new Double ( 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 |