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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  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.server;
  17. import java.io.Serializable;
  18. import java.lang.annotation.Annotation;
  19. import com.vaadin.annotations.PreserveOnRefresh;
  20. import com.vaadin.annotations.Push;
  21. import com.vaadin.annotations.Theme;
  22. import com.vaadin.annotations.Title;
  23. import com.vaadin.annotations.Widgetset;
  24. import com.vaadin.shared.communication.PushMode;
  25. import com.vaadin.shared.ui.ui.Transport;
  26. import com.vaadin.ui.UI;
  27. public abstract class UIProvider implements Serializable {
  28. public abstract Class<? extends UI> getUIClass(UIClassSelectionEvent event);
  29. public UI createInstance(UICreateEvent event) {
  30. try {
  31. return event.getUIClass().newInstance();
  32. } catch (InstantiationException e) {
  33. throw new RuntimeException("Could not instantiate UI class", e);
  34. } catch (IllegalAccessException e) {
  35. throw new RuntimeException("Could not access UI class", e);
  36. }
  37. }
  38. /**
  39. * Helper to get an annotation for a class. If the annotation is not present
  40. * on the target class, its super classes and implemented interfaces are
  41. * also searched for the annotation.
  42. *
  43. * @param clazz
  44. * the class from which the annotation should be found
  45. * @param annotationType
  46. * the annotation type to look for
  47. * @return an annotation of the given type, or <code>null</code> if the
  48. * annotation is not present on the class
  49. */
  50. protected static <T extends Annotation> T getAnnotationFor(Class<?> clazz,
  51. Class<T> annotationType) {
  52. // Find from the class hierarchy
  53. Class<?> currentType = clazz;
  54. while (currentType != Object.class) {
  55. T annotation = currentType.getAnnotation(annotationType);
  56. if (annotation != null) {
  57. return annotation;
  58. } else {
  59. currentType = currentType.getSuperclass();
  60. }
  61. }
  62. // Find from an implemented interface
  63. for (Class<?> iface : clazz.getInterfaces()) {
  64. T annotation = iface.getAnnotation(annotationType);
  65. if (annotation != null) {
  66. return annotation;
  67. }
  68. }
  69. return null;
  70. }
  71. /**
  72. * Finds the theme to use for a specific UI. If no specific theme is
  73. * required, <code>null</code> is returned.
  74. * <p>
  75. * The default implementation checks for a @{@link Theme} annotation on the
  76. * UI class.
  77. *
  78. * @param event
  79. * the UI create event with information about the UI and the
  80. * current request.
  81. * @return the name of the theme, or <code>null</code> if the default theme
  82. * should be used
  83. *
  84. */
  85. public String getTheme(UICreateEvent event) {
  86. Theme uiTheme = getAnnotationFor(event.getUIClass(), Theme.class);
  87. if (uiTheme != null) {
  88. return uiTheme.value();
  89. } else {
  90. return null;
  91. }
  92. }
  93. /**
  94. * Finds the widgetset to use for a specific UI. If no specific widgetset is
  95. * required, <code>null</code> is returned.
  96. * <p>
  97. * The default implementation uses the @{@link Widgetset} annotation if it's
  98. * defined for the UI class.
  99. *
  100. * @param event
  101. * the UI create event with information about the UI and the
  102. * current request.
  103. * @return the name of the widgetset, or <code>null</code> if the default
  104. * widgetset should be used
  105. *
  106. */
  107. public String getWidgetset(UICreateEvent event) {
  108. Widgetset uiWidgetset = getAnnotationFor(event.getUIClass(),
  109. Widgetset.class);
  110. if (uiWidgetset != null) {
  111. return uiWidgetset.value();
  112. } else {
  113. return null;
  114. }
  115. }
  116. /**
  117. * Checks whether the same UI state should be reused if the framework can
  118. * detect that the application is opened in a browser window where it has
  119. * previously been open. The framework attempts to discover this by checking
  120. * the value of window.name in the browser.
  121. * <p>
  122. * Whenever a preserved UI is reused, its
  123. * {@link UI#refresh(com.vaadin.server.VaadinRequest) refresh} method is
  124. * invoked by the framework first.
  125. *
  126. *
  127. * @param event
  128. * the UI create event with information about the UI and the
  129. * current request.
  130. *
  131. * @return <code>true</code>if the same UI instance should be reused e.g.
  132. * when the browser window is refreshed.
  133. */
  134. public boolean isPreservedOnRefresh(UICreateEvent event) {
  135. PreserveOnRefresh preserveOnRefresh = getAnnotationFor(
  136. event.getUIClass(), PreserveOnRefresh.class);
  137. return preserveOnRefresh != null;
  138. }
  139. public String getPageTitle(UICreateEvent event) {
  140. Title titleAnnotation = getAnnotationFor(event.getUIClass(),
  141. Title.class);
  142. if (titleAnnotation == null) {
  143. return null;
  144. } else {
  145. return titleAnnotation.value();
  146. }
  147. }
  148. /**
  149. * Finds the {@link PushMode} to use for a specific UI. If no specific push
  150. * mode is required, <code>null</code> is returned.
  151. * <p>
  152. * The default implementation uses the @{@link Push} annotation if it's
  153. * defined for the UI class.
  154. *
  155. * @param event
  156. * the UI create event with information about the UI and the
  157. * current request.
  158. * @return the push mode to use, or <code>null</code> if the default push
  159. * mode should be used
  160. *
  161. */
  162. public PushMode getPushMode(UICreateEvent event) {
  163. Push push = getAnnotationFor(event.getUIClass(), Push.class);
  164. if (push == null) {
  165. return null;
  166. } else {
  167. return push.value();
  168. }
  169. }
  170. /**
  171. * Finds the {@link Transport} to use for a specific UI. If no transport is
  172. * defined, <code>null</code> is returned.
  173. * <p>
  174. * The default implementation uses the @{@link Push} annotation if it's
  175. * defined for the UI class.
  176. *
  177. * @param event
  178. * the UI create event with information about the UI and the
  179. * current request.
  180. * @return the transport type to use, or <code>null</code> if the default
  181. * transport type should be used
  182. */
  183. public Transport getPushTransport(UICreateEvent event) {
  184. Push push = getAnnotationFor(event.getUIClass(), Push.class);
  185. if (push == null) {
  186. return null;
  187. } else {
  188. return push.transport();
  189. }
  190. }
  191. }