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.

AbstractConnector.java 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /*
  2. @VaadinApache2LicenseForJavaFiles@
  3. */
  4. package com.vaadin.terminal.gwt.client.ui;
  5. import java.util.ArrayList;
  6. import java.util.Collection;
  7. import java.util.Collections;
  8. import java.util.HashMap;
  9. import java.util.List;
  10. import java.util.Map;
  11. import com.google.gwt.event.shared.GwtEvent;
  12. import com.google.gwt.event.shared.HandlerManager;
  13. import com.google.web.bindery.event.shared.HandlerRegistration;
  14. import com.vaadin.shared.communication.ClientRpc;
  15. import com.vaadin.shared.communication.SharedState;
  16. import com.vaadin.terminal.gwt.client.ApplicationConnection;
  17. import com.vaadin.terminal.gwt.client.ServerConnector;
  18. import com.vaadin.terminal.gwt.client.Util;
  19. import com.vaadin.terminal.gwt.client.VConsole;
  20. import com.vaadin.terminal.gwt.client.communication.StateChangeEvent;
  21. import com.vaadin.terminal.gwt.client.communication.StateChangeEvent.StateChangeHandler;
  22. /**
  23. * An abstract implementation of Connector.
  24. *
  25. * @author Vaadin Ltd
  26. * @since 7.0.0
  27. *
  28. */
  29. public abstract class AbstractConnector implements ServerConnector,
  30. StateChangeHandler {
  31. private ApplicationConnection connection;
  32. private String id;
  33. private HandlerManager handlerManager;
  34. private Map<String, Collection<ClientRpc>> rpcImplementations;
  35. private final boolean debugLogging = false;
  36. private SharedState state;
  37. private ServerConnector parent;
  38. /**
  39. * Temporary storage for last enabled state to be able to see if it has
  40. * changed. Can be removed once we are able to listen specifically for
  41. * enabled changes in the state. Widget.isEnabled() cannot be used as all
  42. * Widgets do not implement HasEnabled
  43. */
  44. private boolean lastEnabledState = true;
  45. private List<ServerConnector> children;
  46. /*
  47. * (non-Javadoc)
  48. *
  49. * @see com.vaadin.terminal.gwt.client.VPaintable#getConnection()
  50. */
  51. @Override
  52. public final ApplicationConnection getConnection() {
  53. return connection;
  54. }
  55. /*
  56. * (non-Javadoc)
  57. *
  58. * @see com.vaadin.terminal.gwt.client.Connector#getId()
  59. */
  60. @Override
  61. public String getConnectorId() {
  62. return id;
  63. }
  64. /**
  65. * Called once by the framework to initialize the connector.
  66. * <p>
  67. * Note that the shared state is not yet available when this method is
  68. * called.
  69. * <p>
  70. * Connector classes should override {@link #init()} instead of this method.
  71. */
  72. @Override
  73. public final void doInit(String connectorId,
  74. ApplicationConnection connection) {
  75. this.connection = connection;
  76. id = connectorId;
  77. addStateChangeHandler(this);
  78. init();
  79. }
  80. /**
  81. * Called when the connector has been initialized. Override this method to
  82. * perform initialization of the connector.
  83. */
  84. // FIXME: It might make sense to make this abstract to force users to
  85. // use init instead of constructor, where connection and id has not yet been
  86. // set.
  87. protected void init() {
  88. }
  89. /**
  90. * Registers an implementation for a server to client RPC interface.
  91. *
  92. * Multiple registrations can be made for a single interface, in which case
  93. * all of them receive corresponding RPC calls.
  94. *
  95. * @param rpcInterface
  96. * RPC interface
  97. * @param implementation
  98. * implementation that should receive RPC calls
  99. * @param <T>
  100. * The type of the RPC interface that is being registered
  101. */
  102. protected <T extends ClientRpc> void registerRpc(Class<T> rpcInterface,
  103. T implementation) {
  104. String rpcInterfaceId = rpcInterface.getName().replaceAll("\\$", ".");
  105. if (null == rpcImplementations) {
  106. rpcImplementations = new HashMap<String, Collection<ClientRpc>>();
  107. }
  108. if (null == rpcImplementations.get(rpcInterfaceId)) {
  109. rpcImplementations.put(rpcInterfaceId, new ArrayList<ClientRpc>());
  110. }
  111. rpcImplementations.get(rpcInterfaceId).add(implementation);
  112. }
  113. /**
  114. * Unregisters an implementation for a server to client RPC interface.
  115. *
  116. * @param rpcInterface
  117. * RPC interface
  118. * @param implementation
  119. * implementation to unregister
  120. */
  121. protected <T extends ClientRpc> void unregisterRpc(Class<T> rpcInterface,
  122. T implementation) {
  123. String rpcInterfaceId = rpcInterface.getName().replaceAll("\\$", ".");
  124. if (null != rpcImplementations
  125. && null != rpcImplementations.get(rpcInterfaceId)) {
  126. rpcImplementations.get(rpcInterfaceId).remove(implementation);
  127. }
  128. }
  129. @Override
  130. public <T extends ClientRpc> Collection<T> getRpcImplementations(
  131. String rpcInterfaceId) {
  132. if (null == rpcImplementations) {
  133. return Collections.emptyList();
  134. }
  135. return (Collection<T>) rpcImplementations.get(rpcInterfaceId);
  136. }
  137. @Override
  138. public void fireEvent(GwtEvent<?> event) {
  139. if (handlerManager != null) {
  140. handlerManager.fireEvent(event);
  141. }
  142. }
  143. protected HandlerManager ensureHandlerManager() {
  144. if (handlerManager == null) {
  145. handlerManager = new HandlerManager(this);
  146. }
  147. return handlerManager;
  148. }
  149. @Override
  150. public HandlerRegistration addStateChangeHandler(StateChangeHandler handler) {
  151. return ensureHandlerManager()
  152. .addHandler(StateChangeEvent.TYPE, handler);
  153. }
  154. @Override
  155. public void onStateChanged(StateChangeEvent stateChangeEvent) {
  156. if (debugLogging) {
  157. VConsole.log("State change event for "
  158. + Util.getConnectorString(stateChangeEvent.getConnector())
  159. + " received by " + Util.getConnectorString(this));
  160. }
  161. updateEnabledState(isEnabled());
  162. }
  163. /*
  164. * (non-Javadoc)
  165. *
  166. * @see com.vaadin.terminal.gwt.client.ServerConnector#onUnregister()
  167. */
  168. @Override
  169. public void onUnregister() {
  170. if (debugLogging) {
  171. VConsole.log("Unregistered connector "
  172. + Util.getConnectorString(this));
  173. }
  174. }
  175. /**
  176. * Returns the shared state object for this connector.
  177. *
  178. * Override this method to define the shared state type for your connector.
  179. *
  180. * @return the current shared state (never null)
  181. */
  182. @Override
  183. public SharedState getState() {
  184. if (state == null) {
  185. state = createState();
  186. }
  187. return state;
  188. }
  189. /**
  190. * Creates a state object with default values for this connector. The
  191. * created state object must be compatible with the return type of
  192. * {@link #getState()}. The default implementation creates a state object
  193. * using GWT.create() using the defined return type of {@link #getState()}.
  194. *
  195. * @return A new state object
  196. */
  197. protected SharedState createState() {
  198. return ConnectorStateFactory.createState(getClass());
  199. }
  200. @Override
  201. public ServerConnector getParent() {
  202. return parent;
  203. }
  204. @Override
  205. public void setParent(ServerConnector parent) {
  206. this.parent = parent;
  207. }
  208. @Override
  209. public List<ServerConnector> getChildren() {
  210. if (children == null) {
  211. return Collections.emptyList();
  212. }
  213. return children;
  214. }
  215. @Override
  216. public void setChildren(List<ServerConnector> children) {
  217. this.children = children;
  218. }
  219. @Override
  220. public boolean isEnabled() {
  221. if (!getState().isEnabled()) {
  222. return false;
  223. }
  224. if (getParent() == null) {
  225. return true;
  226. } else {
  227. return getParent().isEnabled();
  228. }
  229. }
  230. @Override
  231. public void updateEnabledState(boolean enabledState) {
  232. if (lastEnabledState == enabledState) {
  233. return;
  234. }
  235. lastEnabledState = enabledState;
  236. for (ServerConnector c : getChildren()) {
  237. // Update children as they might be affected by the enabled state of
  238. // their parent
  239. c.updateEnabledState(c.isEnabled());
  240. }
  241. }
  242. }