You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

JavaScriptCallbackHelper.java 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /*
  2. @VaadinApache2LicenseForJavaFiles@
  3. */
  4. package com.vaadin.terminal;
  5. import java.io.Serializable;
  6. import java.lang.reflect.Method;
  7. import java.util.Arrays;
  8. import java.util.HashMap;
  9. import java.util.HashSet;
  10. import java.util.Map;
  11. import java.util.Set;
  12. import com.vaadin.external.json.JSONArray;
  13. import com.vaadin.external.json.JSONException;
  14. import com.vaadin.shared.JavaScriptConnectorState;
  15. import com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper;
  16. import com.vaadin.tools.ReflectTools;
  17. import com.vaadin.ui.AbstractJavaScriptComponent;
  18. import com.vaadin.ui.JavaScript.JavaScriptCallbackRpc;
  19. import com.vaadin.ui.JavaScriptCallback;
  20. /**
  21. * Internal helper class used to implement functionality common to
  22. * {@link AbstractJavaScriptComponent} and {@link AbstractJavaScriptExtension}.
  23. * Corresponding support in client-side code is in
  24. * {@link JavaScriptConnectorHelper}.
  25. * <p>
  26. * You should most likely no use this class directly.
  27. *
  28. * @author Vaadin Ltd
  29. * @version @VERSION@
  30. * @since 7.0.0
  31. */
  32. public class JavaScriptCallbackHelper implements Serializable {
  33. private static final Method CALL_METHOD = ReflectTools.findMethod(
  34. JavaScriptCallbackRpc.class, "call", String.class, JSONArray.class);
  35. private AbstractClientConnector connector;
  36. private Map<String, JavaScriptCallback> callbacks = new HashMap<String, JavaScriptCallback>();
  37. private JavaScriptCallbackRpc javascriptCallbackRpc;
  38. public JavaScriptCallbackHelper(AbstractClientConnector connector) {
  39. this.connector = connector;
  40. }
  41. public void registerCallback(String functionName,
  42. JavaScriptCallback javaScriptCallback) {
  43. callbacks.put(functionName, javaScriptCallback);
  44. JavaScriptConnectorState state = getConnectorState();
  45. if (state.getCallbackNames().add(functionName)) {
  46. connector.requestRepaint();
  47. }
  48. ensureRpc();
  49. }
  50. private JavaScriptConnectorState getConnectorState() {
  51. JavaScriptConnectorState state = (JavaScriptConnectorState) connector
  52. .getState();
  53. return state;
  54. }
  55. private void ensureRpc() {
  56. if (javascriptCallbackRpc == null) {
  57. javascriptCallbackRpc = new JavaScriptCallbackRpc() {
  58. @Override
  59. public void call(String name, JSONArray arguments) {
  60. JavaScriptCallback callback = callbacks.get(name);
  61. try {
  62. callback.call(arguments);
  63. } catch (JSONException e) {
  64. throw new IllegalArgumentException(e);
  65. }
  66. }
  67. };
  68. connector.registerRpc(javascriptCallbackRpc);
  69. }
  70. }
  71. public void invokeCallback(String name, Object... arguments) {
  72. if (callbacks.containsKey(name)) {
  73. throw new IllegalStateException(
  74. "Can't call callback "
  75. + name
  76. + " on the client because a callback with the same name is registered on the server.");
  77. }
  78. JSONArray args = new JSONArray(Arrays.asList(arguments));
  79. connector.addMethodInvocationToQueue(
  80. JavaScriptCallbackRpc.class.getName(), CALL_METHOD,
  81. new Object[] { name, args });
  82. connector.requestRepaint();
  83. }
  84. public void registerRpc(Class<?> rpcInterfaceType) {
  85. if (rpcInterfaceType == JavaScriptCallbackRpc.class) {
  86. // Ignore
  87. return;
  88. }
  89. Map<String, Set<String>> rpcInterfaces = getConnectorState()
  90. .getRpcInterfaces();
  91. String interfaceName = rpcInterfaceType.getName();
  92. if (!rpcInterfaces.containsKey(interfaceName)) {
  93. Set<String> methodNames = new HashSet<String>();
  94. for (Method method : rpcInterfaceType.getMethods()) {
  95. methodNames.add(method.getName());
  96. }
  97. rpcInterfaces.put(interfaceName, methodNames);
  98. connector.requestRepaint();
  99. }
  100. }
  101. }