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
*/