您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

WidgetSet.java 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*
  2. @VaadinApache2LicenseForJavaFiles@
  3. */
  4. package com.vaadin.terminal.gwt.client;
  5. import com.google.gwt.core.client.GWT;
  6. import com.google.gwt.user.client.ui.Widget;
  7. import com.vaadin.terminal.gwt.client.ui.VFilterSelect;
  8. import com.vaadin.terminal.gwt.client.ui.VListSelect;
  9. import com.vaadin.terminal.gwt.client.ui.VSplitPanelHorizontal;
  10. import com.vaadin.terminal.gwt.client.ui.VSplitPanelVertical;
  11. import com.vaadin.terminal.gwt.client.ui.VUnknownComponent;
  12. import com.vaadin.terminal.gwt.client.ui.VView;
  13. import com.vaadin.terminal.gwt.client.ui.VWindow;
  14. public class WidgetSet {
  15. /**
  16. * WidgetSet (and its extensions) delegate instantiation of widgets and
  17. * client-server matching to WidgetMap. The actual implementations are
  18. * generated with gwts generators/deferred binding.
  19. */
  20. private WidgetMap widgetMap = GWT.create(WidgetMap.class);
  21. /**
  22. * Create an uninitialized component that best matches given UIDL. The
  23. * component must be a {@link Widget} that implements {@link VPaintableWidget}.
  24. *
  25. * @param uidl
  26. * UIDL to be painted with returned component.
  27. * @param client
  28. * the application connection that whishes to instantiate widget
  29. *
  30. * @return New uninitialized and unregistered component that can paint given
  31. * UIDL.
  32. */
  33. public VPaintableWidget createWidget(UIDL uidl, ApplicationConfiguration conf) {
  34. /*
  35. * Yes, this (including the generated code in WidgetMap) may look very
  36. * odd code, but due the nature of GWT, we cannot do this any cleaner.
  37. * Luckily this is mostly written by WidgetSetGenerator, here are just
  38. * some hacks. Extra instantiation code is needed if client side widget
  39. * has no "native" counterpart on client side.
  40. *
  41. * TODO should try to get rid of these exceptions here
  42. */
  43. final Class<? extends VPaintableWidget> classType = resolveWidgetType(uidl,
  44. conf);
  45. if (classType == null || classType == VUnknownComponent.class) {
  46. String serverSideName = conf
  47. .getUnknownServerClassNameByEncodedTagName(uidl.getTag());
  48. VUnknownComponent c = GWT.create(VUnknownComponent.class);
  49. c.setServerSideClassName(serverSideName);
  50. return c;
  51. } else if (VWindow.class == classType) {
  52. return GWT.create(VWindow.class);
  53. } else {
  54. /*
  55. * let the auto generated code instantiate this type
  56. */
  57. return widgetMap.instantiate(classType);
  58. }
  59. }
  60. protected Class<? extends VPaintableWidget> resolveWidgetType(UIDL uidl,
  61. ApplicationConfiguration conf) {
  62. final String tag = uidl.getTag();
  63. Class<? extends VPaintableWidget> widgetClass = conf
  64. .getWidgetClassByEncodedTag(tag);
  65. // add our historical quirks
  66. if (widgetClass == VView.class && uidl.hasAttribute("sub")) {
  67. return VWindow.class;
  68. } else if (widgetClass == VFilterSelect.class) {
  69. if (uidl.hasAttribute("type")) {
  70. final String type = uidl.getStringAttribute("type").intern();
  71. if ("legacy-multi" == type) {
  72. return VListSelect.class;
  73. }
  74. }
  75. } else if (widgetClass == VSplitPanelHorizontal.class
  76. && uidl.hasAttribute("vertical")) {
  77. return VSplitPanelVertical.class;
  78. }
  79. return widgetClass;
  80. }
  81. /**
  82. * Test if the given component implementation conforms to UIDL.
  83. *
  84. * @param currentWidget
  85. * Current implementation of the component
  86. * @param uidl
  87. * UIDL to test against
  88. * @return true iff createWidget would return a new component of the same
  89. * class than currentWidget
  90. */
  91. public boolean isCorrectImplementation(Widget currentWidget, UIDL uidl,
  92. ApplicationConfiguration conf) {
  93. return currentWidget.getClass() == resolveWidgetType(uidl, conf);
  94. }
  95. /**
  96. * Due its nature, GWT does not support dynamic classloading. To bypass this
  97. * limitation, widgetset must have function that returns Class by its fully
  98. * qualified name.
  99. *
  100. * @param fullyQualifiedName
  101. * @param applicationConfiguration
  102. * @return
  103. */
  104. public Class<? extends VPaintableWidget> getImplementationByClassName(
  105. String fullyqualifiedName) {
  106. if (fullyqualifiedName == null) {
  107. return VUnknownComponent.class;
  108. }
  109. Class<? extends VPaintableWidget> implementationByServerSideClassName = widgetMap
  110. .getImplementationByServerSideClassName(fullyqualifiedName);
  111. /*
  112. * Also ensure that our historical quirks have their instantiators
  113. * loaded. Without these, legacy code will throw NPEs when e.g. a Select
  114. * is in multiselect mode, causing the clientside implementation to
  115. * *actually* be VListSelect, when the annotation says VFilterSelect
  116. */
  117. if (fullyqualifiedName.equals("com.vaadin.ui.Select")) {
  118. loadImplementation(VListSelect.class);
  119. } else if (fullyqualifiedName.equals("com.vaadin.ui.SplitPanel")) {
  120. loadImplementation(VSplitPanelVertical.class);
  121. }
  122. return implementationByServerSideClassName;
  123. }
  124. public Class<? extends VPaintableWidget>[] getDeferredLoadedWidgets() {
  125. return widgetMap.getDeferredLoadedWidgets();
  126. }
  127. public void loadImplementation(Class<? extends VPaintableWidget> nextType) {
  128. widgetMap.ensureInstantiator(nextType);
  129. }
  130. }