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