package org.simantics.workbench.search; import java.io.File; import java.io.IOException; import java.net.URL; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.simantics.db.layer0.genericrelation.IndexQueries; public class SearchQuery { private String originalQuery; private Map searchFlags = new HashMap(); private Set searchParams = new HashSet(); public SearchQuery() { } public SearchQuery(String originalQuery) { this.originalQuery = originalQuery; } public void setOriginalQuery(String originalQuery) { this.originalQuery = originalQuery; } public String getOriginalQuery() { return originalQuery; } public String getQuery(Set supportedParams) { if (originalQuery.trim().isEmpty()) return ""; String query = ""; int count = 0; for (String key : searchFlags.keySet()) { if (!supportedParams.contains(key)) continue; if (!"on".equals(searchFlags.get(key))) continue; if (count > 0) query += " OR "; // String prefix = originalQuery.startsWith("*") ? "" : "*"; // String suffix = originalQuery.endsWith("*") ? "" : "*"; // query += key+":"+prefix+originalQuery+suffix; query += key+":"+originalQuery; count++; } return query; } public String getQuery(String... supportedParams) { Set set = new HashSet(); for (String s : supportedParams) set.add(s); return getQuery(set); } public void setSearchFlag(String key, String value) { searchFlags.put(key, value); } public void setSearchParam(String key) { searchParams.add(key); } public Map getSearchFlags() { return Collections.unmodifiableMap(searchFlags); } public Set getSearchParams() { return Collections.unmodifiableSet(searchParams); } public boolean getBooleanFlag(String key) { if ("on".equals(searchFlags.get(key))) return true; return false; } public boolean getBooleanParam(String key) { if (searchParams.contains(key)) return true; return false; } @Override public String toString() { return originalQuery; } public SearchQuery withOriginalQuery(String query) { SearchQuery ret = new SearchQuery(query); ret.searchFlags = new HashMap(searchFlags); ret.searchParams = new HashSet(searchParams); return ret; } public SearchQuery escaped(boolean escapeWildcards) { return withOriginalQuery( IndexQueries.escape( originalQuery, escapeWildcards ) ); } /** * @param uppercase true for uppercased query, false * for lowercased query * @return a clone of this query with the query string in lower or uppercase */ public SearchQuery withForcedCase(boolean uppercase) { return withOriginalQuery(uppercase ? originalQuery.toUpperCase() : originalQuery.toLowerCase()); } /** * @param uppercase true for uppercased query, * false for lowercased query * @param escapeWildcards passed to {@link #escaped(boolean)} * @return a clone of this query with the query string escaped and in lower or * uppercase */ public SearchQuery escapedWithForcedCase(boolean uppercase, boolean escapeWildcards) { return withForcedCase(uppercase).escaped(escapeWildcards); } public static URL encode(File file, SearchQuery query) throws IOException { URL url = file.toURI().toURL(); String s = url.toString() + "?search=" + URLEncoder.encode(query.getOriginalQuery(), "UTF-8"); Map flags = query.getSearchFlags(); for (String key : flags.keySet()) { s += "&"+key+"="+flags.get(key); } for (String param : query.getSearchParams()) { s += "&"+param; } url = new URL(s); return url; } public static SearchQuery decode(URL url) throws IOException{ String query = url.getQuery(); SearchQuery searchQuery = new SearchQuery(); if (query != null) { for (String arg : query.split("&")) { String[] keyvalue = arg.split("="); if ("search".equals(keyvalue[0])) { if (keyvalue.length == 2) searchQuery.setOriginalQuery(URLDecoder.decode(keyvalue[1], "UTF-8")); } else if (keyvalue.length == 2){ searchQuery.setSearchFlag(URLDecoder.decode(keyvalue[0], "UTF-8"), URLDecoder.decode(keyvalue[1], "UTF-8")); } else if (keyvalue.length == 1) { searchQuery.setSearchParam(URLDecoder.decode(keyvalue[0], "UTF-8")); } } } return searchQuery; } }