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.

Dependency.java 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /*
  2. * Copyright 2000-2016 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.ui;
  17. import java.io.Serializable;
  18. import java.lang.annotation.Annotation;
  19. import java.util.ArrayList;
  20. import java.util.List;
  21. import com.vaadin.annotations.HtmlImport;
  22. import com.vaadin.annotations.JavaScript;
  23. import com.vaadin.annotations.StyleSheet;
  24. import com.vaadin.server.ClientConnector;
  25. import com.vaadin.server.DependencyFilter;
  26. import com.vaadin.server.DependencyFilter.FilterContext;
  27. import com.vaadin.server.LegacyCommunicationManager;
  28. import com.vaadin.server.VaadinService;
  29. /**
  30. * Represents a stylesheet or JavaScript to include on the page.
  31. *
  32. * @author Vaadin Ltd
  33. * @since 8.0
  34. */
  35. public class Dependency implements Serializable {
  36. /**
  37. * The type of dependency.
  38. */
  39. public enum Type {
  40. STYLESHEET(StyleSheet.class), //
  41. JAVASCRIPT(JavaScript.class), //
  42. HTMLIMPORT(HtmlImport.class);
  43. private Class<? extends Annotation> annotationType;
  44. private Type(Class<? extends Annotation> annotationType) {
  45. this.annotationType = annotationType;
  46. }
  47. }
  48. private final Type type;
  49. private final String url;
  50. /**
  51. * Creates a new dependency of the given type, to be loaded from the given
  52. * URL.
  53. * <p>
  54. * The URL is passed through the translation mechanism before loading, so
  55. * custom protocols such as "vaadin://" can be used.
  56. *
  57. * @param type
  58. * the type of dependency, not <code>null</code>
  59. * @param url
  60. * the URL to load the dependency from, not <code>null</code>
  61. */
  62. public Dependency(Type type, String url) {
  63. if (url == null) {
  64. throw new IllegalArgumentException("url cannot be null");
  65. }
  66. assert type != null;
  67. this.type = type;
  68. this.url = url;
  69. }
  70. /**
  71. * Gets the untranslated URL for the dependency.
  72. *
  73. * @return the URL for the dependency
  74. */
  75. public String getUrl() {
  76. return url;
  77. }
  78. /**
  79. * Gets the type of the dependency.
  80. *
  81. * @return the type of the dependency
  82. */
  83. public Type getType() {
  84. return type;
  85. }
  86. /**
  87. * Finds all the URLs defined for the given class using annotations for the
  88. * given type, registers the URLs to the communication manager and adds the
  89. * registered dependencies to the given list.
  90. *
  91. * @param type
  92. * the type of dependencies to look for
  93. * @param cls
  94. * the class to scan
  95. * @param manager
  96. * a reference to the communication manager which tracks
  97. * dependencies
  98. * @param dependencies
  99. * the list to add registered dependencies to
  100. *
  101. * @return a stream of resource URLs in the order defined by the annotations
  102. */
  103. @SuppressWarnings("deprecation")
  104. private static void findAndRegisterResources(Type type,
  105. Class<? extends ClientConnector> cls,
  106. LegacyCommunicationManager manager, List<Dependency> dependencies) {
  107. Annotation[] annotations = cls
  108. .getAnnotationsByType(type.annotationType);
  109. if (annotations != null) {
  110. for (Annotation annotation : annotations) {
  111. String[] resources;
  112. if (annotation instanceof StyleSheet) {
  113. resources = ((StyleSheet) annotation).value();
  114. } else if (annotation instanceof JavaScript) {
  115. resources = ((JavaScript) annotation).value();
  116. } else if (annotation instanceof HtmlImport) {
  117. resources = ((HtmlImport) annotation).value();
  118. } else {
  119. throw new IllegalArgumentException(
  120. "Unknown annotation type: "
  121. + annotation.annotationType().getName());
  122. }
  123. for (String resource : resources) {
  124. String url = manager.registerDependency(resource, cls);
  125. dependencies.add(new Dependency(type, url));
  126. }
  127. }
  128. }
  129. }
  130. /**
  131. * Finds all the URLs defined for the given classes, registers the URLs to
  132. * the communication manager and returns the registered dependencies.
  133. * <p>
  134. * The returned collection contains all types of dependencies for each class
  135. * in the given list in the order the classes are in the list, i.e. all
  136. * dependencies for the first class before all dependencies for the next
  137. * class.
  138. * <p>
  139. * JavaScript dependencies are returned before HTML imports.
  140. *
  141. * @param connectorTypes
  142. * the collection of connector classes to scan
  143. * @param manager
  144. * a reference to the communication manager which tracks
  145. * dependencies
  146. * @return the list of found dependencies
  147. */
  148. @SuppressWarnings("deprecation")
  149. public static List<Dependency> findDependencies(
  150. List<Class<? extends ClientConnector>> connectorTypes,
  151. LegacyCommunicationManager manager) {
  152. List<Dependency> dependencies = new ArrayList<>();
  153. for (Class<? extends ClientConnector> connectorType : connectorTypes) {
  154. findAndRegisterResources(Type.JAVASCRIPT, connectorType, manager,
  155. dependencies);
  156. findAndRegisterResources(Type.HTMLIMPORT, connectorType, manager,
  157. dependencies);
  158. findAndRegisterResources(Type.STYLESHEET, connectorType, manager,
  159. dependencies);
  160. }
  161. return dependencies;
  162. }
  163. /**
  164. * Finds all the URLs defined for the given classes, registers the URLs to
  165. * the communication manager, passes the registered dependencies through any
  166. * defined filters and returns the filtered collection of dependencies to
  167. * load.
  168. *
  169. * @since
  170. * @param connectorTypes
  171. * the collection of connector classes to scan
  172. * @param manager
  173. * a reference to the communication manager which tracks
  174. * dependencies
  175. * @param context
  176. * the context information for the filtering operation
  177. * @return the list of found and filtered dependencies
  178. */
  179. public static List<Dependency> findAndFilterDependencies(
  180. List<Class<? extends ClientConnector>> connectorTypes,
  181. LegacyCommunicationManager manager, FilterContext context) {
  182. List<Dependency> dependencies = findDependencies(connectorTypes,
  183. manager);
  184. VaadinService service = context.getService();
  185. for (DependencyFilter filter : service.getDependencyFilters()) {
  186. dependencies = filter.filter(dependencies, context);
  187. }
  188. return dependencies;
  189. }
  190. }