package water.api; import hex.GridSearch; import java.util.*; import water.H2O; import water.util.RString; /** * * @author peta */ public class RequestQueries extends RequestArguments { /** Overwrite this method to be able to change / disable values of other * arguments on certain argument changes. * * This is done for both query checking and request checking. */ protected void queryArgumentValueSet(Argument arg, Properties inputArgs) { } /** Checks the given arguments. * * When first argument is found wrong, generates the json error and returns the * result to be returned if any problems were found. Otherwise returns * * @param args * @param type * @return */ protected final String checkArguments(Properties args, RequestType type) { // Why the following lines duplicate lines from Request#92 - handling query? // reset all arguments for (Argument arg: _arguments) arg.reset(); // return query if in query mode if (type == RequestType.query) return buildQuery(args,type); /* // Check that for each actual input argument from the user, there is some // request argument that this method is expecting. //*/ if (H2O.OPT_ARGS.check_rest_params && !(this instanceof GridSearch) && !(this instanceof HTTP500)) { Enumeration en = args.propertyNames(); while (en.hasMoreElements()) { boolean found = false; String key = (String) en.nextElement(); for (Argument arg: _arguments) { if (arg._name.equals(key)) { found = true; break; } } if (!found) { return jsonError("Request specifies the argument '"+key+"' but it is not a valid parameter for this query " + this.getClass().getName()).toString(); } } } // check the arguments now for (Argument arg: _arguments) { if (!arg.disabled()) { try { arg.check(RequestQueries.this, args.getProperty(arg._name,"")); queryArgumentValueSet(arg, args); } catch( IllegalArgumentException e ) { if (type == RequestType.json) return jsonError("Argument '"+arg._name+"' error: "+e.getMessage()).toString(); else return buildQuery(args,type); } } } return null; } protected static final String _queryHtml = "<div class='container'>" + "<div class='row-fluid'>" + "<div class='span12'>" + "<h3>Request %REQ_NAME <a href='%REQ_NAME.help'><i class='icon-question-sign'></i></a></h3>" + "<p></p>" + " <dl class='dl-horizontal'><dt></dt><dd>" + " <button class='btn btn-primary' onclick='query_submit()'>Submit</button>" + " <button class='btn btn-info' onclick='query_refresh(event || window.event)'>Refresh</button>" + " <button class='btn' onclick='query_reset()'>Reset</button>" + " </dd></dl>" + " %QUERY" + " <dl class='dl-horizontal'><dt></dt><dd>" + " <button class='btn btn-primary' onclick='query_submit()'>Submit</button>" + " <button class='btn btn-info' onclick='query_refresh(event || window.event)'>Refresh</button>" + " <button class='btn' onclick='query_reset()'>Reset</button>" + " </dd></dl>" + " <script type='text/javascript'>" + " %SCRIPT" + " </script>" + "</div></div></div>" ; private static final String _queryJs = "\nfunction query_refresh(event) {\n" + " query_submit('.query', event.data, null);\n" + "}\n" + "function query_submit(requestType, specArg, specValue) {\n" + " if (typeof(requestType) === 'undefined')\n" + " requestType='.html';\n" + " var request = {};\n" + " %REQUEST_ELEMENT{" + "%ELEMENT_PREQ request.%ELEMENT_NAME = query_value_%ELEMENT_NAME();\n" + " }\n" + " var location = '%REQUEST_NAME'+requestType+'?'+$.param(request);\n" + " if (requestType == '.query') {\n" + " window.location.replace(location);\n" + " } else {\n" + " window.location = location;\n" + " }\n" + "}\n" + "function query_reset() {\n" + " window.location.replace('%REQUEST_NAME.query');\n" + "}\n" + "%ELEMENT_VALUE{ %BODY\n }" + "%ELEMENT_ADDONS{ %BODY\n }" + "%ELEMENT_ONCHANGE{ %BODY\n }" ; /** Returns the request query form produced from the given input arguments. */ protected String buildQuery(Properties parms, RequestType type) { if (parms.isEmpty()) type = RequestType.query; RString result = new RString(_queryHtml); result.replace("REQ_NAME", this.getClass().getSimpleName()); StringBuilder query = new StringBuilder(); query.append("<form onsubmit='return false;'>"); RString script = new RString(_queryJs); script.replace("REQUEST_NAME", getClass().getSimpleName()); for (Argument arg: _arguments) { try { arg.check(RequestQueries.this, parms.getProperty(arg._name,"")); queryArgumentValueSet(arg, parms); } catch( IllegalArgumentException e ) { // in query mode only display error for arguments present if ((type != RequestType.query) || !parms.getProperty(arg._name,"").isEmpty()) query.append("<div class='alert alert-error'>"+e.getMessage()+"</div>"); } if (arg._hideInQuery) continue; if (!arg.disabled()) { RString x = script.restartGroup("REQUEST_ELEMENT"); x.replace("ELEMENT_NAME",arg._name); // If some Argument has prerequisites, and those pre-reqs changed on // this very page load then we do not assign the arg here: the values // passed will be something valid from the PRIOR page - based on the // old pre-req - and won't be correct. Not assigning them here means // we'll act "as if" the field was never filled in. if( arg._prerequisites != null ) { StringBuilder sb = new StringBuilder("if( "); ArrayList<RequestArguments.Argument> preqs = arg._prerequisites; for( RequestArguments.Argument dep : preqs ) sb.append("specArg!=='").append(dep._name).append("' && "); sb.append("true ) "); x.replace("ELEMENT_PREQ",sb); } x.append(); x = script.restartGroup("ELEMENT_VALUE"); x.replace("ELEMENT_NAME",arg._name); x.replace("BODY","function query_value_"+arg._name+"() { "+arg.jsValue()+"} "); x.append(); } if (arg.refreshOnChange()) { RString x = script.restartGroup("ELEMENT_ONCHANGE"); x.replace("BODY",arg.jsRefresh("query_refresh")); x.append(); } RString x = script.restartGroup("ELEMENT_ADDONS"); x.replace("BODY", arg.jsAddons()); x.append(); } for(Argument arg:_arguments){ if (arg._hideInQuery) continue; query.append(arg.query()); } query.append("</form>"); result.replace("QUERY",query.toString()); result.replace("SCRIPT",script.toString()); return result.toString(); } }