package org.genedb.web.mvc.controller; import org.genedb.query.BasicQueryI; import org.genedb.query.NumberedQueryI; import org.genedb.query.QueryPlaceHolder; import org.genedb.query.bool.BooleanOp; import org.genedb.query.bool.BooleanQuery; import org.genedb.web.tags.bool.QueryTreeWalker; import org.springframework.beans.factory.InitializingBean; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.multiaction.MultiActionController; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * <code>MultiActionController</code> that handles all non-form URL's. * * @author Adrian Tivey */ public class ComplexQueryController extends MultiActionController implements InitializingBean { public void afterPropertiesSet() throws Exception { // Deliberately empty } // handlers /** * Custom handler for examples * * @param request current HTTP request * @param response current HTTP response * @return a ModelAndView to render the response */ public ModelAndView BooleanQuery(HttpServletRequest request, HttpServletResponse response) { List<String> answers = new ArrayList<String>(); if (!webUtils.extractTaxonNodesFromRequest(request, answers, true, false)) { return new ModelAndView("chooseTaxon"); } QueryForm qf = parseQueryForm(0, request); NumberedQueryI q = qf.getNumberedQueryI(); if (q == null) { q = new QueryPlaceHolder(); qf.setNumberedQuery(q); } // boolean submitPressed = false; if ("Run".equals(request.getParameter("runquery"))) { if (q.isComplete()) { return new ModelAndView("resultListView"); } // query not complete - fall back to query page } else { // Check for set expansion... for (Object o : request.getParameterMap().keySet()) { String key = (String) o; if (key.startsWith("bop.")) { String[] parts = key.split("\\."); BooleanOp op = BooleanOp.valueOf(parts[1]); int q1 = Integer.parseInt(parts[2]); q = replaceNode(q, q1, op); QueryTreeWalker qtw = new QueryTreeWalker(q, 0); qtw.go(); break; } } // Now let's see if an expansion was requested } Map<String,Object> model = new HashMap<String,Object>(); model.put(WebConstants.QUERY_FORM, qf); model.put(WebConstants.TAX_ID, answers.get(0)); return new ModelAndView("queryWorking", WebConstants.MODEL_MAP, model); } private NumberedQueryI replaceNode(NumberedQueryI q, int q1, BooleanOp op) { if (q1 == 0) { return new BooleanQuery(op, q, new QueryPlaceHolder()); } recurseTree(q, q1, op); return q; } private boolean recurseTree(BasicQueryI q, int q1, BooleanOp op) { // Looking for parent... if (!(q instanceof BooleanQuery)) { return false; } BooleanQuery bool = (BooleanQuery) q; if (bool.getFirstQuery().getIndex() == q1) { BasicQueryI node = bool.getFirstQuery(); BooleanQuery newNode = new BooleanQuery(op, node, new QueryPlaceHolder()); bool.setFirstQuery(newNode); return true; } if (bool.getSecondQuery().getIndex() == q1) { BasicQueryI node = bool.getSecondQuery(); BooleanQuery newNode = new BooleanQuery(op, node, new QueryPlaceHolder()); bool.setSecondQuery(newNode); return true; } if (recurseTree(bool.getFirstQuery(), q1, op)) { return true; } return recurseTree(bool.getSecondQuery(), q1, op); } /** * @param index * @param request * @return */ private QueryForm parseQueryForm(int index, HttpServletRequest request) { QueryForm qf = new QueryForm(); qf.setNumberedQuery(parseQuery(index, request)); return qf; } /** * @param index * @param request * @return */ private NumberedQueryI parseQuery(int index, HttpServletRequest request) { String value = request.getParameter("node." + index); if (value == null) { return null; } if (value.startsWith("bool.")) { String[] parts = value.split("\\."); BooleanOp op = BooleanOp.valueOf(parts[1]); int q1 = Integer.parseInt(parts[2]); BasicQueryI query1 = parseQuery(q1, request); int q2 = Integer.parseInt(parts[3]); BasicQueryI query2 = parseQuery(q2, request); NumberedQueryI q = new BooleanQuery(op, query1, query2); q.setIndex(index); return q; } // String name = request.getParameter("question."+index); QueryPlaceHolder qph = new QueryPlaceHolder(); if (!"none".equals(value)) { qph.setName(value); } qph.setIndex(index); return qph; } private GeneDBWebUtils webUtils; public void setWebUtils(GeneDBWebUtils webutils) { this.webUtils = webutils; } }