1package autotest.tko; 2 3import autotest.common.JsonRpcCallback; 4import autotest.common.JsonRpcProxy; 5import autotest.common.Utils; 6import autotest.tko.TableView.TableSwitchListener; 7 8import com.google.gwt.core.client.GWT; 9import com.google.gwt.core.client.JavaScriptObject; 10import com.google.gwt.core.client.GWT.UncaughtExceptionHandler; 11import com.google.gwt.json.client.JSONObject; 12import com.google.gwt.json.client.JSONString; 13import com.google.gwt.json.client.JSONValue; 14import com.google.gwt.user.client.ui.Composite; 15import com.google.gwt.user.client.ui.HTML; 16 17abstract 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 31 public void onSuccess(JSONValue result) {} 32 } 33 34 public Plot(String rpcName) { 35 this.rpcName = rpcName; 36 this.callbackName = getFreshCallbackName(); 37 initWidget(plotElement); 38 } 39 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 */ 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 */ 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) 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 88 protected abstract void showDrilldownImpl(JSONObject drilldownParams); 89 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 106 public void refresh(JSONObject params) { 107 refresh(params, new DummyRpcCallback()); 108 } 109 110 public void setListener(TableSwitchListener listener) { 111 this.listener = listener; 112 } 113} 114