/* Kweelt - a framework to query XML documents * Copyright (C) 2000, Arnaud Sahuguet (Arnaud.Sahuguet@polytechnique.org) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package xacute.ksp; import java.util.Dictionary; import java.util.Enumeration; import java.util.Hashtable; import javax.servlet.http.*; import org.w3c.dom.*; import org.apache.cocoon.framework.*; import org.apache.cocoon.processor.*; import org.apache.regexp.RE; import org.xml.sax.DocumentHandler; import xacute.quilt.QuiltParser; import xacute.quilt.QuiltQuery; import xacute.quilt.EvalContext; public class KweeltProcessor extends AbstractActor implements Processor, Status { /** * * parameters contains two items of type org.apache.jserv.JServConnection * - request * - response * **/ /** * The kweelt engine processes trees of the form * * Kweelt query * * * to produce trees of the form * * * * Kweelt result * * * * We need to enclose the request in a tag because we * need a top level tag for Cocoon to behave properly when we * replace the query with the result. * **/ public Document process(Document doc, Dictionary parameters) throws Exception { /** * We build a hashtable of parameters passed from the url in * the QUERY_STRING. **/ Hashtable params; HttpServletRequest req = (HttpServletRequest)parameters.get("request"); if (req.getQueryString() != null) params = HttpUtils.parseQueryString( req.getQueryString() ); else params = new Hashtable(); NodeList kweelt_nodes = doc.getElementsByTagName("kweelt"); for(int i=0; i < kweelt_nodes.getLength(); i++) processKweeltQuery(doc, kweelt_nodes.item(i), params); return doc; } public void processKweeltQuery(Document doc, Node kweeltNode, Hashtable params) { Node kweeltQueryNode; String query; try { kweeltQueryNode = ((Element) kweeltNode).getElementsByTagName("kweelt-query").item(0); query = kweeltQueryNode.getFirstChild().getNodeValue(); } catch(Exception e) { // we cannot find enough info to process anything Element errorEl = doc.createElement("kweelt-error"); errorEl.appendChild( doc.createTextNode(e.toString()) ); kweeltNode.appendChild( errorEl ); return; } Element resultEl = doc.createElement("kweelt-result"); Element dataEl = doc.createElement("data"); resultEl.appendChild(dataEl); kweeltNode.replaceChild(resultEl, kweeltQueryNode); QuiltParser parser = new QuiltParser(); QuiltQuery q; EvalContext con = new EvalContext(); SAX2DOM handler = new SAX2DOM(doc, dataEl); long t1; // parsing try { query = rewriteQuery(query, params); t1 = System.currentTimeMillis(); q = parser.parseQuery(query); resultEl.setAttribute("parsingTime", (System.currentTimeMillis() - t1) + "ms"); resultEl.setAttribute("parsing", "OK" ); } catch(Exception e) { resultEl.setAttribute("parsing", "FAIL" ); Element parseLog = doc.createElement("ParsingLog"); parseLog.appendChild( doc.createTextNode(e.toString())); resultEl.appendChild( parseLog ); return; } // execution try { t1 = System.currentTimeMillis(); q.eval( handler, con ); resultEl.setAttribute("executionTime", (System.currentTimeMillis() - t1) + "ms"); resultEl.setAttribute("execution", "OK" ); } catch(Exception e) { resultEl.setAttribute("execution", "FAIL" ); Element execLog = doc.createElement("ExecLog"); execLog.appendChild( doc.createTextNode(e.toString())); resultEl.appendChild( execLog ); } return; } public boolean hasChanged(Object o) { return true; } public String getStatus() { return "Kweelt Processor"; } /** used to remove "{@" and "}" around a variable name **/ private final static String chop(String s) { return s.substring(2, s.length()-1); } private final static String rewriteQuery(String query, Hashtable bindings) throws Exception { RE regex = new RE("([{]@[:alnum:]+[}])"); String s = query; StringBuffer buf = new StringBuffer(); int i = 0; while( regex.match(s, i) ) { String var = chop(regex.getParen(0)); if (!bindings.containsKey(var)) throw new Exception("missing binding: " + var); buf.append( s.substring(i, regex.getParenStart(0) ) + ((String[]) bindings.get(var))[0]); i = regex.getParenEnd(0); } buf.append( s.substring(i) ); return buf.toString(); } } /** * A processor that performs Kweelt queries * * XML file format:

 *<?xml version="1.0"?>
 *<?xml-stylesheet href="kweelt.xsl" type="text/xsl"?>
 *
 *<?cocoon-process type="kweelt"?>
 *<?cocoon-process type="xslt"?>
 *
 *<page>
 *
 *
 *
 *</page>
 *
* * * adapted from Donald Ball's SQLProcessor and James Birchfield's * LdapProcessor code. * * @author Arnaud Sahuguet * @version 1.0 */