package org.cdlib.xtf.crossQuery; /* * Copyright (c) 2006, 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.util.HashMap; import net.sf.saxon.om.NodeInfo; import org.cdlib.xtf.util.EasyNode; import org.cdlib.xtf.util.GeneralException; /** * Routes a request to a particular query parser. Optionally contains * special tokenizing instructions for one or more URL parameters. */ public class QueryRoute { /** Path to the query parser stylesheet */ public String queryParserSheet; /** Optional: path to the error generator stylesheet */ public String errorGenSheet; /** Special parsing requests for particular URL parameters */ public HashMap tokenizerMap = new HashMap(); /** Optional: input to query router stylesheet */ public String routerInput = null; /** Optional: output from query router stylesheet */ public String routerOutput = null; /** Do not construct directly -- use {@link #parse(NodeInfo)} */ protected QueryRoute() { } /** * Create a default route to the given query parser */ public static QueryRoute createDefault(String queryParserSheet) { QueryRoute ret = new QueryRoute(); ret.queryParserSheet = queryParserSheet; return ret; } // createDefault() /** * Reads and parses the route output from a queryRouter stylesheet. * * @param input The output from a queryRouter stylesheet * @throws GeneralException If a read or parse error occurs. */ public static QueryRoute parse(NodeInfo input) throws GeneralException { // Create the (empty) result QueryRoute ret = new QueryRoute(); // Make sure the root tag is correct. EasyNode root = new EasyNode(input); String rootTag = root.name(); if (rootTag.equals("") && root.nChildren() == 1) { root = root.child(0); rootTag = root.name(); } if (!rootTag.equalsIgnoreCase("route")) throw new QueryRouteException( "Query router stylesheet must output a 'route' element"); // Pick out the elements for (int i = 0; i < root.nChildren(); i++) { EasyNode el = root.child(i); if (!el.isElement()) continue; // Was a query parser specified? String tagName = el.name(); if (tagName.equalsIgnoreCase("queryParser")) ret.parseQueryParser(el); else if (tagName.equalsIgnoreCase("errorGen")) ret.parseErrorGen(el); else if (tagName.equalsIgnoreCase("tokenize")) ret.parseTokenizer(el); } // for i // Make sure that required parameters were specified. if (ret.queryParserSheet == null || ret.queryParserSheet.length() == 0) throw new QueryRouteException( "Query router stylesheet must output a 'queryParser' element"); return ret; } // parse() /** * Parse a 'queryParser' element */ private void parseQueryParser(EasyNode el) { // Scan each attribute of each element. for (int j = 0; j < el.nAttrs(); j++) { if (el.attrName(j).equalsIgnoreCase("path")) queryParserSheet = el.attrValue(j); else { throw new GeneralException( "Query router attribute " + el.name() + "." + el.attrName(j) + " not recognized"); } } } // parseQueryParser() /** * Parse a 'errorGen' element */ private void parseErrorGen(EasyNode el) { // Scan each attribute of each element. for (int j = 0; j < el.nAttrs(); j++) { if (el.attrName(j).equalsIgnoreCase("path")) errorGenSheet = el.attrValue(j); else { throw new GeneralException( "Query router attribute " + el.name() + "." + el.attrName(j) + " not recognized"); } } } // parseErrorGen() /** * Parse a 'tokenize' element */ private void parseTokenizer(EasyNode el) { String paramName = null; String tokenizer = null; // Scan each attribute of each element. for (int j = 0; j < el.nAttrs(); j++) { if (el.attrName(j).equalsIgnoreCase("param")) paramName = el.attrValue(j); else if (el.attrName(j).equalsIgnoreCase("tokenizer")) tokenizer = el.attrValue(j); else { throw new GeneralException( "Query router attribute " + el.name() + "." + el.attrName(j) + " not recognized"); } } // Make sure both specified. if (paramName == null || tokenizer == null) throw new GeneralException( el.name() + " element requires 'param' and 'tokenizer' attributes to be specified"); // Add it. tokenizerMap.put(paramName, tokenizer); } // parseTokenizer() } // class QueryRoute