package org.cdlib.xtf.zing; /** * Copyright (c) 2004, Regents of the University of California * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the University of California nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ import java.io.IOException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.transform.Source; import net.sf.saxon.om.NodeInfo; import org.cdlib.xtf.crossQuery.CrossQuery; import org.cdlib.xtf.crossQuery.QueryRoute; import org.cdlib.xtf.servletBase.TextConfig; import org.cdlib.xtf.textEngine.QueryProcessor; import org.cdlib.xtf.textEngine.QueryRequest; import org.cdlib.xtf.textEngine.QueryResult; import org.cdlib.xtf.util.AttribList; import org.cdlib.xtf.util.EasyNode; import org.cdlib.xtf.util.XMLWriter; /** * The SRU servlet coordinates the process of parsing a URL query, * activating the textEngine to find all occurrences, and finally formatting * the results. */ public class SRU extends CrossQuery { // inherit JavaDoc public String getConfigName() { return "conf/sru.conf"; } // inherit JavaDoc protected TextConfig readConfig(String configPath) { // Load the configuration file. config = new SRUConfig(this, configPath); // And we're done. return config; } // readConfig() // inherit JavaDoc public TextConfig getConfig() { return config; } // inherit JavaDoc public String getServletInfo() { return "SRU servlet"; } // getServletInfo() // inherit JavaDoc protected void apply(AttribList attribs, HttpServletRequest req, HttpServletResponse res) throws Exception { // Record the start time. long startTime = System.currentTimeMillis(); // Switch the default output mode to XML. res.setContentType("text/xml"); // Make a default route, but set up to do CQL parsing on the query // parameter instead of the default tokenization. // QueryRoute route = QueryRoute.createDefault(config.queryParserSheet); route.tokenizerMap.put("query", "CQL"); // Generate a query request document from the queryParser stylesheet. QueryRequest queryReq = runQueryParser(req, res, route, attribs); if (queryReq == null) return; // Process it to generate result document hits QueryProcessor proc = createQueryProcessor(); QueryResult result = proc.processRequest(queryReq); // Format the hits for the output document. Include the <parameters> block // and the actual query request, in case the stylesheet wants to use these // things. // formatHits("SRUResult", req, res, attribs, queryReq, result, startTime); } /** * Called right after the raw query request has been generated, but * before it is parsed. Gives us a chance to stop processing here in * if SRW diagnostics should be output instead of running a query. */ protected boolean shuntQueryReq(HttpServletRequest req, HttpServletResponse res, Source queryReqDoc) throws IOException { // If it actually contains an SRW explain response, or an SRW // diagnostic, simply output that directly. // EasyNode node = new EasyNode((NodeInfo)queryReqDoc); if (directOutput(node, "diagnostics", res)) return true; if (directOutput(node, "explainResponse", res)) return true; return super.shuntQueryReq(req, res, queryReqDoc); } // shuntQueryReq() /** Add additional stuff to the usual debug step mode */ protected String stepSetup(HttpServletRequest req, HttpServletResponse res) throws IOException { String stepStr = super.stepSetup(req, res); if (stepStr != null) { stepStr = stepStr.replaceAll("crossQuery", "SRU"); String step = req.getParameter("debugStep"); if (step.equals("2a")) stepStr = stepStr.replaceAll("Next,", "Note that the 'query' parameter has been " + "parsed as CQL. Next,"); stepStr = stepStr.replaceAll("final HTML", "final SRW-formatted XML"); stepStr = stepStr.replaceAll("XML page", "XML result"); } return stepStr; } /** * Scans the node and its descendants for an SRW 'explainResponse' or * 'diagnostics'. If found, it is output directly. * * @param node Node to scan * @param name Name to scan for * @return true if direct output was made */ private boolean directOutput(EasyNode node, String name, HttpServletResponse res) throws IOException { // If the node is an explainResponse or diagnostic, output it // directly. // if (name.equals(node.name())) { String strVal = XMLWriter.toString(node); res.getWriter().print(strVal); return true; } // Scan the children. for (int i = 0; i < node.nChildren(); i++) { if (directOutput(node.child(i), name, res)) return true; } // None found in this branch. return false; } // directOutput() } // class SRU