1 package autotest.tko; 2 3 import autotest.common.JsonRpcCallback; 4 import autotest.common.JsonRpcProxy; 5 import autotest.common.Utils; 6 import autotest.tko.TableView.TableSwitchListener; 7 8 import com.google.gwt.core.client.GWT; 9 import com.google.gwt.core.client.JavaScriptObject; 10 import com.google.gwt.core.client.GWT.UncaughtExceptionHandler; 11 import com.google.gwt.json.client.JSONObject; 12 import com.google.gwt.json.client.JSONString; 13 import com.google.gwt.json.client.JSONValue; 14 import com.google.gwt.user.client.ui.Composite; 15 import com.google.gwt.user.client.ui.HTML; 16 17 abstract class Plot extends Composite { 18 private static final String CALLBACK_PREFIX = "__plot_drilldown"; 19 20 private static int callbackNameCounter = 0; 21 protected final static JsonRpcProxy rpcProxy = JsonRpcProxy.getProxy(); 22 23 private String rpcName; 24 private HTML plotElement = new HTML(); 25 protected TableSwitchListener listener; 26 27 private String callbackName; 28 29 private static class DummyRpcCallback extends JsonRpcCallback { 30 @Override onSuccess(JSONValue result)31 public void onSuccess(JSONValue result) {} 32 } 33 Plot(String rpcName)34 public Plot(String rpcName) { 35 this.rpcName = rpcName; 36 this.callbackName = getFreshCallbackName(); 37 initWidget(plotElement); 38 } 39 getFreshCallbackName()40 private static String getFreshCallbackName() { 41 callbackNameCounter++; 42 return CALLBACK_PREFIX + callbackNameCounter; 43 } 44 45 /** 46 * This function is called at initialization time and allows the plot to put native 47 * callbacks in place for drilldown functionality from graphs. 48 */ setDrilldownTrigger()49 public native void setDrilldownTrigger() /*-{ 50 var instance = this; 51 var name = this.@autotest.tko.Plot::callbackName; 52 $wnd[name] = function(drilldownParams) { 53 instance.@autotest.tko.Plot::showDrilldown(Lcom/google/gwt/core/client/JavaScriptObject;)(drilldownParams); 54 } 55 }-*/; 56 57 /** 58 * Get a native JS object that acts as a proxy to this object. Currently the only exposed 59 * method is refresh(params), where params is a JS object. This is only necessary for allowing 60 * externally-written native code to use this object without having to write out the full JSNI 61 * method call syntax. 62 */ getNativeProxy()63 public native JavaScriptObject getNativeProxy() /*-{ 64 var instance = this; 65 return { 66 refresh: function(params) { 67 jsonObjectParams = @com.google.gwt.json.client.JSONObject::new(Lcom/google/gwt/core/client/JavaScriptObject;)(params); 68 instance.@autotest.tko.Plot::refresh(Lcom/google/gwt/json/client/JSONObject;)(jsonObjectParams); 69 } 70 }; 71 }-*/; 72 73 @SuppressWarnings("unused") // called from native code (see setDrilldownTrigger) showDrilldown(JavaScriptObject drilldownParamsJso)74 private void showDrilldown(JavaScriptObject drilldownParamsJso) { 75 UncaughtExceptionHandler handler = GWT.getUncaughtExceptionHandler(); 76 if (handler == null) { 77 showDrilldownImpl(new JSONObject(drilldownParamsJso)); 78 return; 79 } 80 81 try { 82 showDrilldownImpl(new JSONObject(drilldownParamsJso)); 83 } catch (Throwable throwable) { 84 handler.onUncaughtException(throwable); 85 } 86 } 87 showDrilldownImpl(JSONObject drilldownParams)88 protected abstract void showDrilldownImpl(JSONObject drilldownParams); 89 refresh(JSONObject params, final JsonRpcCallback callback)90 public void refresh(JSONObject params, final JsonRpcCallback callback) { 91 params.put("drilldown_callback", new JSONString(callbackName)); 92 rpcProxy.rpcCall(rpcName, params, new JsonRpcCallback() { 93 @Override 94 public void onSuccess(JSONValue result) { 95 plotElement.setHTML(Utils.jsonToString(result)); 96 callback.onSuccess(result); 97 } 98 99 @Override 100 public void onError(JSONObject errorObject) { 101 callback.onError(errorObject); 102 } 103 }); 104 } 105 refresh(JSONObject params)106 public void refresh(JSONObject params) { 107 refresh(params, new DummyRpcCallback()); 108 } 109 setListener(TableSwitchListener listener)110 public void setListener(TableSwitchListener listener) { 111 this.listener = listener; 112 } 113 } 114