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.

DesignResourceConverter.java 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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.declarative.converters;
  17. import java.io.File;
  18. import java.io.Serializable;
  19. import java.util.Arrays;
  20. import java.util.HashMap;
  21. import java.util.Locale;
  22. import java.util.Map;
  23. import java.util.stream.Collectors;
  24. import com.vaadin.data.Converter;
  25. import com.vaadin.data.Result;
  26. import com.vaadin.data.ValueContext;
  27. import com.vaadin.icons.VaadinIcons;
  28. import com.vaadin.server.ExternalResource;
  29. import com.vaadin.server.FileResource;
  30. import com.vaadin.server.FontAwesome;
  31. import com.vaadin.server.FontIcon;
  32. import com.vaadin.server.GenericFontIcon;
  33. import com.vaadin.server.Resource;
  34. import com.vaadin.server.ResourceReference;
  35. import com.vaadin.server.ThemeResource;
  36. import com.vaadin.ui.declarative.DesignAttributeHandler;
  37. /**
  38. * A converter for {@link Resource} implementations supported by
  39. * {@link DesignAttributeHandler}.
  40. *
  41. * @author Vaadin Ltd
  42. * @since 7.4
  43. */
  44. @SuppressWarnings("serial")
  45. public class DesignResourceConverter implements Converter<String, Resource> {
  46. private static final Map<Integer, VaadinIcons> CODE_POINTS = Arrays
  47. .stream(VaadinIcons.values())
  48. .collect(Collectors.toMap(VaadinIcons::getCodepoint, icon -> icon));
  49. @Override
  50. public Result<Resource> convertToModel(String value, ValueContext context) {
  51. if (!value.contains("://")) {
  52. // assume it'is "file://" protocol, one that is used to access a
  53. // file on a given path on the server, this will later be striped
  54. // out anyway
  55. value = "file://" + value;
  56. }
  57. String protocol = value.split("://")[0];
  58. try {
  59. ResourceConverterByProtocol converter = ResourceConverterByProtocol
  60. .valueOf(protocol.toUpperCase(Locale.ENGLISH));
  61. return Result.ok(converter.parse(value));
  62. } catch (IllegalArgumentException iae) {
  63. return Result.error("Unrecognized protocol: " + protocol);
  64. }
  65. }
  66. @Override
  67. public String convertToPresentation(Resource value, ValueContext context) {
  68. ResourceConverterByProtocol byType = ResourceConverterByProtocol
  69. .byType(value.getClass());
  70. if (byType != null) {
  71. return byType.format(value);
  72. } else {
  73. throw new IllegalArgumentException(
  74. "unknown Resource type - " + value.getClass().getName());
  75. }
  76. }
  77. private static interface ProtocolResourceConverter extends Serializable {
  78. public String format(Resource value);
  79. public Resource parse(String value);
  80. }
  81. private static enum ResourceConverterByProtocol
  82. implements ProtocolResourceConverter {
  83. HTTP, HTTPS, FTP, FTPS, THEME {
  84. @Override
  85. public Resource parse(String value) {
  86. // strip "theme://" from the url, use the rest as the resource
  87. // id
  88. return new ThemeResource(value.substring(8));
  89. }
  90. @Override
  91. public String format(Resource value) {
  92. return new ResourceReference(value, null, null).getURL();
  93. }
  94. },
  95. FONTICON {
  96. @Override
  97. public Resource parse(String value) {
  98. final String address = value.split("://", 2)[1];
  99. final String[] familyAndCode = address.split("/", 2);
  100. final int codepoint = Integer.valueOf(familyAndCode[1], 16);
  101. if (VAADIN_ICONS_NAME.equals(familyAndCode[0])) {
  102. return CODE_POINTS.get(codepoint);
  103. }
  104. if (FontAwesome.FONT_FAMILY.equals(familyAndCode[0])) { // Left
  105. // for
  106. // compatibility
  107. return FontAwesome.fromCodepoint(codepoint);
  108. }
  109. // all vaadin icons should have a codepoint
  110. FontIcon generic = new GenericFontIcon(familyAndCode[0],
  111. codepoint);
  112. return generic;
  113. }
  114. @Override
  115. public String format(Resource value) {
  116. FontIcon icon = (FontIcon) value;
  117. return new ResourceReference(icon, null, null).getURL();
  118. }
  119. },
  120. @Deprecated
  121. FONT {
  122. @Override
  123. public Resource parse(String value) {
  124. // Deprecated, 7.4 syntax is
  125. // font://"+FontAwesome.valueOf(foo) eg. "font://AMBULANCE"
  126. final String iconName = value.split("://", 2)[1];
  127. return FontAwesome.valueOf(iconName);
  128. }
  129. @Override
  130. public String format(Resource value) {
  131. throw new UnsupportedOperationException("Use "
  132. + ResourceConverterByProtocol.FONTICON + " instead");
  133. }
  134. },
  135. FILE {
  136. @Override
  137. public Resource parse(String value) {
  138. return new FileResource(new File(value.split("://")[1]));
  139. }
  140. @Override
  141. public String format(Resource value) {
  142. String path = ((FileResource) value).getSourceFile().getPath();
  143. if (File.separatorChar != '/') {
  144. // make sure we use '/' as file separator in templates
  145. return path.replace(File.separatorChar, '/');
  146. } else {
  147. return path;
  148. }
  149. }
  150. };
  151. public static final String VAADIN_ICONS_NAME = VaadinIcons.ABACUS
  152. .getFontFamily();
  153. @Override
  154. public Resource parse(String value) {
  155. // default behavior for HTTP, HTTPS, FTP and FTPS
  156. return new ExternalResource(value);
  157. }
  158. @Override
  159. public String format(Resource value) {
  160. // default behavior for HTTP, HTTPS, FTP and FTPS
  161. return ((ExternalResource) value).getURL();
  162. }
  163. private static final Map<Class<? extends Resource>, ResourceConverterByProtocol> typeToConverter = new HashMap<>();
  164. static {
  165. typeToConverter.put(ExternalResource.class, HTTP);
  166. // ^ any of non-specialized would actually work
  167. typeToConverter.put(ThemeResource.class, THEME);
  168. typeToConverter.put(FontIcon.class, FONTICON);
  169. typeToConverter.put(FileResource.class, FILE);
  170. }
  171. public static ResourceConverterByProtocol byType(
  172. Class<? extends Resource> resourceType) {
  173. for (Class<?> type : typeToConverter.keySet()) {
  174. if (type.isAssignableFrom(resourceType)) {
  175. return typeToConverter.get(type);
  176. }
  177. }
  178. return null;
  179. }
  180. }
  181. }