123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- /*
- @VaadinApache2LicenseForJavaFiles@
- */
-
- package com.vaadin.terminal.gwt.client;
-
- import com.google.gwt.core.client.GWT;
- import com.google.gwt.user.client.ui.Widget;
- import com.vaadin.terminal.gwt.client.ui.VFilterSelect;
- import com.vaadin.terminal.gwt.client.ui.VListSelect;
- import com.vaadin.terminal.gwt.client.ui.VSplitPanelHorizontal;
- import com.vaadin.terminal.gwt.client.ui.VSplitPanelVertical;
- import com.vaadin.terminal.gwt.client.ui.VUnknownComponent;
- import com.vaadin.terminal.gwt.client.ui.VView;
- import com.vaadin.terminal.gwt.client.ui.VWindow;
-
- public class WidgetSet {
-
- /**
- * WidgetSet (and its extensions) delegate instantiation of widgets and
- * client-server matching to WidgetMap. The actual implementations are
- * generated with gwts generators/deferred binding.
- */
- private WidgetMap widgetMap = GWT.create(WidgetMap.class);
-
- /**
- * Create an uninitialized component that best matches given UIDL. The
- * component must be a {@link Widget} that implements {@link VPaintableWidget}.
- *
- * @param uidl
- * UIDL to be painted with returned component.
- * @param client
- * the application connection that whishes to instantiate widget
- *
- * @return New uninitialized and unregistered component that can paint given
- * UIDL.
- */
- public VPaintableWidget createWidget(UIDL uidl, ApplicationConfiguration conf) {
- /*
- * Yes, this (including the generated code in WidgetMap) may look very
- * odd code, but due the nature of GWT, we cannot do this any cleaner.
- * Luckily this is mostly written by WidgetSetGenerator, here are just
- * some hacks. Extra instantiation code is needed if client side widget
- * has no "native" counterpart on client side.
- *
- * TODO should try to get rid of these exceptions here
- */
-
- final Class<? extends VPaintableWidget> classType = resolveWidgetType(uidl,
- conf);
- if (classType == null || classType == VUnknownComponent.class) {
- String serverSideName = conf
- .getUnknownServerClassNameByEncodedTagName(uidl.getTag());
- VUnknownComponent c = GWT.create(VUnknownComponent.class);
- c.setServerSideClassName(serverSideName);
- return c;
- } else if (VWindow.class == classType) {
- return GWT.create(VWindow.class);
- } else {
- /*
- * let the auto generated code instantiate this type
- */
- return widgetMap.instantiate(classType);
- }
-
- }
-
- protected Class<? extends VPaintableWidget> resolveWidgetType(UIDL uidl,
- ApplicationConfiguration conf) {
- final String tag = uidl.getTag();
-
- Class<? extends VPaintableWidget> widgetClass = conf
- .getWidgetClassByEncodedTag(tag);
-
- // add our historical quirks
-
- if (widgetClass == VView.class && uidl.hasAttribute("sub")) {
- return VWindow.class;
- } else if (widgetClass == VFilterSelect.class) {
- if (uidl.hasAttribute("type")) {
- final String type = uidl.getStringAttribute("type").intern();
- if ("legacy-multi" == type) {
- return VListSelect.class;
- }
- }
- } else if (widgetClass == VSplitPanelHorizontal.class
- && uidl.hasAttribute("vertical")) {
- return VSplitPanelVertical.class;
- }
-
- return widgetClass;
-
- }
-
- /**
- * Test if the given component implementation conforms to UIDL.
- *
- * @param currentWidget
- * Current implementation of the component
- * @param uidl
- * UIDL to test against
- * @return true iff createWidget would return a new component of the same
- * class than currentWidget
- */
- public boolean isCorrectImplementation(Widget currentWidget, UIDL uidl,
- ApplicationConfiguration conf) {
- return currentWidget.getClass() == resolveWidgetType(uidl, conf);
- }
-
- /**
- * Due its nature, GWT does not support dynamic classloading. To bypass this
- * limitation, widgetset must have function that returns Class by its fully
- * qualified name.
- *
- * @param fullyQualifiedName
- * @param applicationConfiguration
- * @return
- */
- public Class<? extends VPaintableWidget> getImplementationByClassName(
- String fullyqualifiedName) {
- if (fullyqualifiedName == null) {
- return VUnknownComponent.class;
- }
- Class<? extends VPaintableWidget> implementationByServerSideClassName = widgetMap
- .getImplementationByServerSideClassName(fullyqualifiedName);
-
- /*
- * Also ensure that our historical quirks have their instantiators
- * loaded. Without these, legacy code will throw NPEs when e.g. a Select
- * is in multiselect mode, causing the clientside implementation to
- * *actually* be VListSelect, when the annotation says VFilterSelect
- */
- if (fullyqualifiedName.equals("com.vaadin.ui.Select")) {
- loadImplementation(VListSelect.class);
- } else if (fullyqualifiedName.equals("com.vaadin.ui.SplitPanel")) {
- loadImplementation(VSplitPanelVertical.class);
- }
-
- return implementationByServerSideClassName;
-
- }
-
- public Class<? extends VPaintableWidget>[] getDeferredLoadedWidgets() {
- return widgetMap.getDeferredLoadedWidgets();
- }
-
- public void loadImplementation(Class<? extends VPaintableWidget> nextType) {
- widgetMap.ensureInstantiator(nextType);
- }
-
- }
|