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.

ConnectorMap.java 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. /*
  2. * Copyright 2000-2014 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.client;
  17. import java.util.ArrayList;
  18. import java.util.Collection;
  19. import java.util.logging.Logger;
  20. import com.google.gwt.core.client.GWT;
  21. import com.google.gwt.core.client.JavaScriptObject;
  22. import com.google.gwt.dom.client.Element;
  23. import com.google.gwt.user.client.ui.Widget;
  24. public class ConnectorMap {
  25. public static ConnectorMap get(ApplicationConnection applicationConnection) {
  26. return applicationConnection.getConnectorMap();
  27. }
  28. @Deprecated
  29. private final ComponentDetailMap idToComponentDetail = ComponentDetailMap
  30. .create();
  31. /**
  32. * Returns a {@link ServerConnector} by its id
  33. *
  34. * @param id
  35. * The connector id
  36. * @return A connector or null if a connector with the given id has not been
  37. * registered
  38. */
  39. public ServerConnector getConnector(String connectorId) {
  40. ComponentDetail componentDetail = idToComponentDetail.get(connectorId);
  41. if (componentDetail == null) {
  42. return null;
  43. } else {
  44. return componentDetail.getConnector();
  45. }
  46. }
  47. /**
  48. * Returns a {@link ComponentConnector} element by its root element.
  49. *
  50. * @param element
  51. * Root element of the {@link ComponentConnector}
  52. * @return A connector or null if a connector with the given id has not been
  53. * registered
  54. */
  55. public ComponentConnector getConnector(Element element) {
  56. ServerConnector connector = getConnector(getConnectorId(element));
  57. if (!(connector instanceof ComponentConnector)) {
  58. // This can happen at least if element is not part of this
  59. // application but is part of another application and the connector
  60. // id happens to map to e.g. an extension in this application
  61. return null;
  62. }
  63. // Ensure this connector is really connected to the element. We cannot
  64. // be sure of this otherwise as the id comes from the DOM and could be
  65. // part of another application.
  66. ComponentConnector cc = (ComponentConnector) connector;
  67. if (cc.getWidget() == null || cc.getWidget().getElement() != element) {
  68. return null;
  69. }
  70. return cc;
  71. }
  72. /**
  73. * FIXME: What does this even do and why?
  74. *
  75. * @param pid
  76. * @return
  77. */
  78. public boolean isDragAndDropPaintable(String pid) {
  79. return (pid.startsWith("DD"));
  80. }
  81. /**
  82. * Checks if a connector with the given id has been registered.
  83. *
  84. * @param connectorId
  85. * The id to check for
  86. * @return true if a connector has been registered with the given id, false
  87. * otherwise
  88. */
  89. public boolean hasConnector(String connectorId) {
  90. return idToComponentDetail.containsKey(connectorId);
  91. }
  92. /**
  93. * Removes all registered connectors
  94. */
  95. public void clear() {
  96. idToComponentDetail.clear();
  97. }
  98. /**
  99. * Retrieves the connector whose widget matches the parameter.
  100. *
  101. * @param widget
  102. * The widget
  103. * @return A connector with {@literal widget} as its root widget or null if
  104. * no connector was found
  105. */
  106. public ComponentConnector getConnector(Widget widget) {
  107. return widget == null ? null : getConnector(widget.getElement());
  108. }
  109. public void registerConnector(String id, ServerConnector connector) {
  110. Profiler.enter("ConnectorMap.registerConnector");
  111. ComponentDetail componentDetail = GWT.create(ComponentDetail.class);
  112. idToComponentDetail.put(id, componentDetail);
  113. componentDetail.setConnector(connector);
  114. if (connector instanceof ComponentConnector) {
  115. ComponentConnector pw = (ComponentConnector) connector;
  116. Widget widget = pw.getWidget();
  117. Profiler.enter("ConnectorMap.setConnectorId");
  118. setConnectorId(widget.getElement(), id);
  119. Profiler.leave("ConnectorMap.setConnectorId");
  120. }
  121. Profiler.leave("ConnectorMap.registerConnector");
  122. }
  123. private static native void setConnectorId(Element el, String id)
  124. /*-{
  125. el.tkPid = id;
  126. }-*/;
  127. /**
  128. * Gets the connector id using a DOM element - the element should be the
  129. * root element for a connector, otherwise no id will be found. Use
  130. * {@link #getConnectorId(ServerConnector)} instead whenever possible.
  131. *
  132. * @see #getConnectorId(ServerConnector)
  133. * @param el
  134. * element of the connector whose id is desired
  135. * @return the id of the element's connector, if it's a connector
  136. */
  137. native static final String getConnectorId(Element el)
  138. /*-{
  139. return el.tkPid;
  140. }-*/;
  141. /**
  142. * Gets the main element for the connector with the given id. The reverse of
  143. * {@link #getConnectorId(Element)}.
  144. *
  145. * @param connectorId
  146. * the id of the widget whose element is desired
  147. * @return the element for the connector corresponding to the id
  148. */
  149. public Element getElement(String connectorId) {
  150. ServerConnector p = getConnector(connectorId);
  151. if (p instanceof ComponentConnector) {
  152. return ((ComponentConnector) p).getWidget().getElement();
  153. }
  154. return null;
  155. }
  156. /**
  157. * Unregisters the given connector; always use after removing a connector.
  158. * This method does not remove the connector from the DOM, but marks the
  159. * connector so that ApplicationConnection may clean up its references to
  160. * it. Removing the widget from DOM is component containers responsibility.
  161. *
  162. * @param connector
  163. * the connector to remove
  164. */
  165. public void unregisterConnector(ServerConnector connector) {
  166. if (connector == null) {
  167. getLogger().severe("Trying to unregister null connector");
  168. return;
  169. }
  170. String connectorId = connector.getConnectorId();
  171. idToComponentDetail.remove(connectorId);
  172. connector.onUnregister();
  173. for (ServerConnector child : connector.getChildren()) {
  174. if (child.getParent() == connector) {
  175. /*
  176. * Only unregister children that are actually connected to this
  177. * parent. For instance when moving connectors from one layout
  178. * to another and removing the first layout it will still
  179. * contain references to its old children, which are now
  180. * attached to another connector.
  181. */
  182. unregisterConnector(child);
  183. }
  184. }
  185. }
  186. /**
  187. * Gets all registered {@link ComponentConnector} instances
  188. *
  189. * @return An array of all registered {@link ComponentConnector} instances
  190. *
  191. * @deprecated As of 7.0.1, use {@link #getComponentConnectorsAsJsArray()}
  192. * for better performance.
  193. */
  194. @Deprecated
  195. public ComponentConnector[] getComponentConnectors() {
  196. ArrayList<ComponentConnector> result = new ArrayList<ComponentConnector>();
  197. JsArrayObject<ServerConnector> connectors = getConnectorsAsJsArray();
  198. int size = connectors.size();
  199. for (int i = 0; i < size; i++) {
  200. ServerConnector connector = connectors.get(i);
  201. if (connector instanceof ComponentConnector) {
  202. result.add((ComponentConnector) connector);
  203. }
  204. }
  205. return result.toArray(new ComponentConnector[result.size()]);
  206. }
  207. public JsArrayObject<ComponentConnector> getComponentConnectorsAsJsArray() {
  208. JsArrayObject<ComponentConnector> result = JavaScriptObject
  209. .createArray().cast();
  210. JsArrayObject<ServerConnector> connectors = getConnectorsAsJsArray();
  211. int size = connectors.size();
  212. for (int i = 0; i < size; i++) {
  213. ServerConnector connector = connectors.get(i);
  214. if (connector instanceof ComponentConnector) {
  215. result.add((ComponentConnector) connector);
  216. }
  217. }
  218. return result;
  219. }
  220. @Deprecated
  221. private ComponentDetail getComponentDetail(
  222. ComponentConnector componentConnector) {
  223. return idToComponentDetail.get(componentConnector.getConnectorId());
  224. }
  225. public int size() {
  226. return idToComponentDetail.size();
  227. }
  228. /**
  229. * @return
  230. *
  231. * @deprecated As of 7.0.1, use {@link #getConnectorsAsJsArray()} for
  232. * improved performance.
  233. */
  234. @Deprecated
  235. public Collection<? extends ServerConnector> getConnectors() {
  236. Collection<ComponentDetail> values = idToComponentDetail.values();
  237. ArrayList<ServerConnector> arrayList = new ArrayList<ServerConnector>(
  238. values.size());
  239. for (ComponentDetail componentDetail : values) {
  240. arrayList.add(componentDetail.getConnector());
  241. }
  242. return arrayList;
  243. }
  244. public JsArrayObject<ServerConnector> getConnectorsAsJsArray() {
  245. JsArrayObject<ComponentDetail> componentDetails = idToComponentDetail
  246. .valuesAsJsArray();
  247. JsArrayObject<ServerConnector> connectors = JavaScriptObject
  248. .createArray().cast();
  249. int size = componentDetails.size();
  250. for (int i = 0; i < size; i++) {
  251. connectors.add(componentDetails.get(i).getConnector());
  252. }
  253. return connectors;
  254. }
  255. /**
  256. * Tests if the widget is the root widget of a {@link ComponentConnector}.
  257. *
  258. * @param widget
  259. * The widget to test
  260. * @return true if the widget is the root widget of a
  261. * {@link ComponentConnector}, false otherwise
  262. */
  263. public boolean isConnector(Widget w) {
  264. return getConnectorId(w.getElement()) != null;
  265. }
  266. private static Logger getLogger() {
  267. return Logger.getLogger(ConnectorMap.class.getName());
  268. }
  269. }