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

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