package org.ariadne_eu.utils.rest; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; import org.json.JSONArray; import org.json.JSONObject; public class Query { public String[][] searchTerms = new String[0][]; //Conjunction of disjunction public String[] exclusionTerms; //Disjunction of terms to be excluded public String[] rankingTerms; //These are terms that should be considered in the ranking; e.g. "cny=BE" public String sortKey; //By which key the results should be sorted public String[] facets = new String[0]; //Which facets to count //public QueryResult result; //QueryResult, consolidated from the nodes //public int maxResults = 0; //Maximum number of results public int resultListOffset = 0; public int resultListSize = 12; public int idListOffset = 0; public int idListSize = 12; public int maxCntFacets = 0; //Maximum number of results that will be counted for the facets public PrintWriter responseWriter = null; public int nrOfThreads; int nodesProcessed = 0; int nrOfNodes; int queryCacheNr = -1; public Query(/*InMemoryEngine eng*/){ // searchEngine = eng; // nrOfNodes = searchEngine.getNrOfNodes(); // nrOfThreads = nrOfNodes; // nodeResult = new QueryResult[nrOfNodes]; // if (facets == null) facets = searchEngine.getFacets(); } public void checkCache() { ArrayList<String[]> temp = new ArrayList<String[]>(); for (int i=0;i<searchTerms.length;i++){ String[] disjunction = searchTerms[i]; boolean found = false; for (int j=0;j<disjunction.length;j++){ //TODO test spaces in search term if (searchTerms[i][j].equalsIgnoreCase("lom.solr:all")){ found = true; break; } } if(!found){ temp.add(disjunction); } } final int dimConj = temp.size(); //Number of disjunctions in the conjunction //TODO if there are no searchTerms assume all //System.out.println(dimConj+" "+qry.toString()); if (dimConj==0 || (dimConj==1 && searchTerms[0].length==0)) { String[][] searchAll = {{"lom.solr:all"}}; searchTerms = searchAll; queryCacheNr = 0; } else { searchTerms = new String[temp.size()][]; temp.toArray(searchTerms); } //System.out.println(toString()); } public void parseTerms(String inp){ inp = inp.substring(inp.indexOf("{")+1, inp.lastIndexOf("}")); String regex = "\\{(.*?)\\}"; //System.out.println(regex + " IN "+inp); Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(inp); ArrayList<ArrayList<String>> conjList = new ArrayList<ArrayList<String>>(); ArrayList<String> disjList; while (matcher.find()) { StringTokenizer st = new StringTokenizer(matcher.group(1),","); disjList = new ArrayList<String>(); while(st.hasMoreTokens()) { String s = st.nextToken().trim().toLowerCase(); s = s.substring(1, s.length()-1).trim(); //System.out.println(s); disjList.add(s); } conjList.add(disjList); } searchTerms = new String[conjList.size()][]; for (int i=0;i<conjList.size();i++){ String disj[] = new String[conjList.get(i).size()]; conjList.get(i).toArray(disj); searchTerms[i] = disj; } } public void parseJson(JSONObject jo){ try { String expression = ""; String language = ""; ArrayList<String[]> stList = new ArrayList<String[]>(); JSONArray clause = new JSONArray(); if (jo.has("clause")) clause = jo.getJSONArray("clause"); for (int i=0;i<clause.length();i++){ JSONObject thisClause = clause.getJSONObject(i); if (thisClause.has("language")) language = thisClause.getString("language").trim(); if (thisClause.has("expression")) expression = thisClause.getString("expression").trim();; if (language.equalsIgnoreCase("vsql")){ stList.addAll(parseVSQL(expression)); } else if (language.equalsIgnoreCase("anyOf")){ String[] parts = expression.split(":"); stList.add(parseAnyOf(parts[0],parts[1],",")); } else if (language.equalsIgnoreCase("anyOfFacet")){ String[] parts = expression.split(":"); stList.add(parseFacet(parts[0],parts[1],",")); } } searchTerms = new String[stList.size()][]; for (int i=0;i<stList.size();i++) searchTerms[i] = stList.get(i); //Set facets to report the numbers on if (jo.has("facets")) { JSONArray myFacets = jo.getJSONArray("facets"); facets = new String[myFacets.length()]; for (int i=0;i<myFacets.length();i++){ facets[i] = myFacets.getString(i); } } if (jo.has("resultListOffset")) resultListOffset = jo.getInt("resultListOffset"); if (jo.has("resultListSize")) resultListSize = jo.getInt("resultListSize"); //Set IDsFrom and IDsTo to default values idListOffset = resultListOffset; idListSize = resultListSize; if (jo.has("idListOffset")) idListOffset = jo.getInt("idListOffset"); if (jo.has("idListSize")) idListSize = jo.getInt("idListSize"); } catch (Exception ex) { System.out.println(ex.getMessage()); ex.printStackTrace (); } //System.out.println(toString()); } public void parseURL(HttpServletRequest request){ try { Map<String,String[]> parMap = request.getParameterMap(); Set<String> parKeys = parMap.keySet(); String[] keys = new String[parKeys.size()]; parKeys.toArray(keys); for (int i=0; i<keys.length;i++){ if (keys[i].equalsIgnoreCase("clause")){ parseURLclauses(parMap.get(keys[i])); } else if (keys[i].equalsIgnoreCase("info")){ parseURLinfo(parMap.get(keys[i])); } else if (keys[i].equalsIgnoreCase("offset")){ resultListOffset = Integer.parseInt(parMap.get(keys[i])[0]); } else if (keys[i].equalsIgnoreCase("limit")){ resultListSize = Integer.parseInt(parMap.get(keys[i])[0]); } } //Set idListOffset and idListSize to default values idListOffset = resultListOffset; idListSize = resultListSize; } catch (Exception ex) { System.out.println(ex.getMessage()); ex.printStackTrace (); } } public void parseURLclauses(String[] values){ ArrayList<String[]> stList = new ArrayList<String[]>(); for (int i=0;i<values.length;i++){ String[] parts = values[i].split(":"); if (parts[0].equalsIgnoreCase("VSQL")){ stList.addAll(parseVSQL(parts[1])); } else if (parts[0].equalsIgnoreCase("facet")){ stList.add(parseFacet(parts[1],parts[2],"|")); } } searchTerms = new String[stList.size()][]; stList.toArray(searchTerms); } public void parseURLinfo(String[] values){ ArrayList<String> facetList = new ArrayList<String>(); for (int i=0;i<values.length;i++){ String[] parts = values[i].split(":"); if (parts[0].equalsIgnoreCase("elementset")){ //TODO } else if (parts[0].equalsIgnoreCase("facet")){ facetList.add(parts[1]); } } facets = new String[facetList.size()]; facetList.toArray(facets); for (int i=0;i<facets.length;i++) System.out.print(" "+facets[i]);System.out.println(); } public List<String[]> parseVSQL(String content){ List<String[]> result = new ArrayList<String[]>(); StringTokenizer st = new StringTokenizer(content, " "); List<String> subject = new ArrayList<String>(); while(st.hasMoreTokens()) { subject.add(st.nextToken().trim().toLowerCase()); } for (int j=0;j<subject.size();j++){ String[] disjunction = new String[1]; disjunction[0] = "contents:"+subject.get(j); result.add(disjunction); } return result; } /* public List<String> parseFacet(String content){ StringTokenizer st = new StringTokenizer(content.substring(1, content.length()-1), ","); List<String> result = new ArrayList<String>(); while(st.hasMoreTokens()) { String f = st.nextToken().trim().toLowerCase(); result.add(f.substring(1, f.length() - 1).trim()); } return result; } */ public String[] parseFacet(String facet, String content, String delim){ StringTokenizer st = new StringTokenizer(content, delim); List<String> parsedFacets = new ArrayList<String>(); while(st.hasMoreTokens()) { String f = st.nextToken().trim(); parsedFacets.add(facet+":\""+f.trim()+"\""); } String[] facetArray = new String[parsedFacets.size()]; parsedFacets.toArray(facetArray); return facetArray; } public String[] parseAnyOf(String field, String content, String delim){ StringTokenizer st = new StringTokenizer(content, delim); List<String> parsedDisjunction = new ArrayList<String>(); while(st.hasMoreTokens()) { //String f = st.nextToken().trim().toLowerCase(); String f = st.nextToken().trim(); parsedDisjunction.add(field+":\""+f+"\""); } String[] disjunctionArray = new String[parsedDisjunction.size()]; parsedDisjunction.toArray(disjunctionArray); return disjunctionArray; } public String toString(){ String result = "{"; for (int i=0;i<searchTerms.length;i++){ result = result+"{"; for (int j=0;j<searchTerms[i].length;j++) { result = result+"\""+searchTerms[i][j]+"\""; if (j!=searchTerms[i].length - 1) result = result+","; } result = result+"}"; if (i!=searchTerms.length - 1) result = result+","; } result = result+"}"; return result; } }