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.

FileTypeResolver.java 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. /*
  2. * Copyright 2000-2018 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.util;
  17. import java.io.File;
  18. import java.io.Serializable;
  19. import java.util.Collections;
  20. import java.util.Locale;
  21. import java.util.Map;
  22. import java.util.StringTokenizer;
  23. import java.util.concurrent.ConcurrentHashMap;
  24. import com.vaadin.server.Resource;
  25. import com.vaadin.server.ThemeResource;
  26. /**
  27. * Utility class that can figure out mime-types and icons related to files.
  28. * <p>
  29. * Note : The icons are associated purely to mime-types, so a file may not have
  30. * a custom icon accessible with this class.
  31. * </p>
  32. *
  33. * @author Vaadin Ltd.
  34. * @since 3.0
  35. */
  36. @SuppressWarnings("serial")
  37. public class FileTypeResolver {
  38. /**
  39. * Default icon given if no icon is specified for a mime-type.
  40. */
  41. public static Resource DEFAULT_ICON = new ThemeResource(
  42. "../runo/icons/16/document.png");
  43. /**
  44. * Default mime-type.
  45. */
  46. public static String DEFAULT_MIME_TYPE = "application/octet-stream";
  47. /**
  48. * Initial file extension to mime-type mapping.
  49. */
  50. private static final String INITIAL_EXT_TO_MIME_MAP = "application/cu-seeme csm cu,"
  51. + "application/dsptype tsp,"
  52. + "application/futuresplash spl,"
  53. + "application/mac-binhex40 hqx,"
  54. + "application/msaccess mdb,"
  55. + "application/msword doc dot,"
  56. + "application/octet-stream bin,"
  57. + "application/oda oda,"
  58. + "application/pdf pdf,"
  59. + "application/pgp-signature pgp,"
  60. + "application/postscript ps ai eps,"
  61. + "application/rtf rtf,"
  62. + "application/vnd.ms-excel xls xlb,"
  63. + "application/vnd.ms-powerpoint ppt pps pot,"
  64. + "application/vnd.wap.wmlc wmlc,"
  65. + "application/vnd.wap.wmlscriptc wmlsc,"
  66. + "application/wordperfect5.1 wp5,"
  67. + "application/zip zip,"
  68. + "application/x-123 wk,"
  69. + "application/x-bcpio bcpio,"
  70. + "application/x-chess-pgn pgn,"
  71. + "application/x-cpio cpio,"
  72. + "application/x-debian-package deb,"
  73. + "application/x-director dcr dir dxr,"
  74. + "application/x-dms dms,"
  75. + "application/x-dvi dvi,"
  76. + "application/x-xfig fig,"
  77. + "application/x-font pfa pfb gsf pcf pcf.Z,"
  78. + "application/x-gnumeric gnumeric,"
  79. + "application/x-gtar gtar tgz taz,"
  80. + "application/x-hdf hdf,"
  81. + "application/x-httpd-php phtml pht php,"
  82. + "application/x-httpd-php3 php3,"
  83. + "application/x-httpd-php3-source phps,"
  84. + "application/x-httpd-php3-preprocessed php3p,"
  85. + "application/x-httpd-php4 php4,"
  86. + "application/x-ica ica,"
  87. + "application/x-java-archive jar,"
  88. + "application/x-java-serialized-object ser,"
  89. + "application/x-java-vm class,"
  90. + "application/x-javascript js,"
  91. + "application/x-kchart chrt,"
  92. + "application/x-killustrator kil,"
  93. + "application/x-kpresenter kpr kpt,"
  94. + "application/x-kspread ksp,"
  95. + "application/x-kword kwd kwt,"
  96. + "application/x-latex latex,"
  97. + "application/x-lha lha,"
  98. + "application/x-lzh lzh,"
  99. + "application/x-lzx lzx,"
  100. + "application/x-maker frm maker frame fm fb book fbdoc,"
  101. + "application/x-mif mif,"
  102. + "application/x-msdos-program com exe bat dll,"
  103. + "application/x-msi msi,"
  104. + "application/x-netcdf nc cdf,"
  105. + "application/x-ns-proxy-autoconfig pac,"
  106. + "application/x-object o,"
  107. + "application/x-ogg ogg,"
  108. + "application/x-oz-application oza,"
  109. + "application/x-perl pl pm,"
  110. + "application/x-pkcs7-crl crl,"
  111. + "application/x-redhat-package-manager rpm,"
  112. + "application/x-shar shar,"
  113. + "application/x-shockwave-flash swf swfl,"
  114. + "application/x-star-office sdd sda,"
  115. + "application/x-stuffit sit,"
  116. + "application/x-sv4cpio sv4cpio,"
  117. + "application/x-sv4crc sv4crc,"
  118. + "application/x-tar tar,"
  119. + "application/x-tex-gf gf,"
  120. + "application/x-tex-pk pk PK,"
  121. + "application/x-texinfo texinfo texi,"
  122. + "application/x-trash ~ % bak old sik,"
  123. + "application/x-troff t tr roff,"
  124. + "application/x-troff-man man,"
  125. + "application/x-troff-me me,"
  126. + "application/x-troff-ms ms,"
  127. + "application/x-ustar ustar,"
  128. + "application/x-wais-source src,"
  129. + "application/x-wingz wz,"
  130. + "application/x-x509-ca-cert crt,"
  131. + "audio/basic au snd,"
  132. + "audio/midi mid midi,"
  133. + "audio/mpeg mpga mpega mp2 mp3,"
  134. + "audio/mpegurl m3u,"
  135. + "audio/prs.sid sid,"
  136. + "audio/x-aiff aif aiff aifc,"
  137. + "audio/x-gsm gsm,"
  138. + "audio/x-pn-realaudio ra rm ram,"
  139. + "audio/x-scpls pls,"
  140. + "audio/x-wav wav,"
  141. + "audio/ogg ogg,"
  142. + "audio/mp4 m4a,"
  143. + "audio/x-aac aac,"
  144. + "image/bitmap bmp,"
  145. + "image/gif gif,"
  146. + "image/ief ief,"
  147. + "image/jpeg jpeg jpg jpe,"
  148. + "image/pcx pcx,"
  149. + "image/png png,"
  150. + "image/svg+xml svg svgz,"
  151. + "image/tiff tiff tif,"
  152. + "image/vnd.wap.wbmp wbmp,"
  153. + "image/x-cmu-raster ras,"
  154. + "image/x-coreldraw cdr,"
  155. + "image/x-coreldrawpattern pat,"
  156. + "image/x-coreldrawtemplate cdt,"
  157. + "image/x-corelphotopaint cpt,"
  158. + "image/x-jng jng,"
  159. + "image/x-portable-anymap pnm,"
  160. + "image/x-portable-bitmap pbm,"
  161. + "image/x-portable-graymap pgm,"
  162. + "image/x-portable-pixmap ppm,"
  163. + "image/x-rgb rgb,"
  164. + "image/x-xbitmap xbm,"
  165. + "image/x-xpixmap xpm,"
  166. + "image/x-xwindowdump xwd,"
  167. + "text/comma-separated-values csv,"
  168. + "text/css css,"
  169. + "text/html htm html xhtml,"
  170. + "text/mathml mml,"
  171. + "text/plain txt text diff,"
  172. + "text/richtext rtx,"
  173. + "text/tab-separated-values tsv,"
  174. + "text/vnd.wap.wml wml,"
  175. + "text/vnd.wap.wmlscript wmls,"
  176. + "text/xml xml,"
  177. + "text/x-c++hdr h++ hpp hxx hh,"
  178. + "text/x-c++src c++ cpp cxx cc,"
  179. + "text/x-chdr h,"
  180. + "text/x-csh csh,"
  181. + "text/x-csrc c,"
  182. + "text/x-java java,"
  183. + "text/x-moc moc,"
  184. + "text/x-pascal p pas,"
  185. + "text/x-setext etx,"
  186. + "text/x-sh sh,"
  187. + "text/x-tcl tcl tk,"
  188. + "text/x-tex tex ltx sty cls,"
  189. + "text/x-vcalendar vcs,"
  190. + "text/x-vcard vcf,"
  191. + "video/dl dl,"
  192. + "video/fli fli,"
  193. + "video/gl gl,"
  194. + "video/mpeg mpeg mpg mpe,"
  195. + "video/quicktime qt mov,"
  196. + "video/x-mng mng,"
  197. + "video/x-ms-asf asf asx,"
  198. + "video/x-msvideo avi,"
  199. + "video/x-sgi-movie movie,"
  200. + "video/ogg ogv,"
  201. + "video/mp4 mp4,"
  202. + "x-world/x-vrml vrm vrml wrl";
  203. /**
  204. * File extension to MIME type mapping. All extensions are in lower case.
  205. */
  206. private static final Map<String, String> EXT_TO_MIME_MAP = new ConcurrentHashMap<>();
  207. static {
  208. // Initialize extension to MIME map
  209. final StringTokenizer lines = new StringTokenizer(
  210. INITIAL_EXT_TO_MIME_MAP, ",");
  211. while (lines.hasMoreTokens()) {
  212. final String line = lines.nextToken();
  213. final StringTokenizer exts = new StringTokenizer(line);
  214. final String type = exts.nextToken();
  215. while (exts.hasMoreTokens()) {
  216. final String ext = exts.nextToken();
  217. addExtension(ext, type);
  218. }
  219. }
  220. }
  221. /**
  222. * Gets the mime-type of a file. Currently the mime-type is resolved based
  223. * only on the file name extension.
  224. *
  225. * @param fileName
  226. * the name of the file whose mime-type is requested.
  227. * @return mime-type <code>String</code> for the given filename
  228. */
  229. public static String getMIMEType(String fileName) {
  230. // Checks for nulls
  231. if (fileName == null) {
  232. throw new NullPointerException("Filename can not be null");
  233. }
  234. // Calculates the extension of the file
  235. int dotIndex = fileName.indexOf('.');
  236. while (dotIndex >= 0 && fileName.indexOf('.', dotIndex + 1) >= 0) {
  237. dotIndex = fileName.indexOf('.', dotIndex + 1);
  238. }
  239. dotIndex++;
  240. if (fileName.length() > dotIndex) {
  241. String ext = fileName.substring(dotIndex);
  242. // Ignore any query parameters
  243. int queryStringStart = ext.indexOf('?');
  244. if (queryStringStart > 0) {
  245. ext = ext.substring(0, queryStringStart);
  246. }
  247. // Return type from extension map, if found
  248. final String type = EXT_TO_MIME_MAP
  249. .get(ext.toLowerCase(Locale.ROOT));
  250. if (type != null) {
  251. return type;
  252. }
  253. }
  254. return DEFAULT_MIME_TYPE;
  255. }
  256. /**
  257. * Gets the mime-type for a file. Currently the returned file type is
  258. * resolved by the filename extension only.
  259. *
  260. * @param file
  261. * the file whose mime-type is requested.
  262. * @return the files mime-type <code>String</code>
  263. */
  264. public static String getMIMEType(File file) {
  265. // Checks for nulls
  266. if (file == null) {
  267. throw new NullPointerException("File can not be null");
  268. }
  269. // Directories
  270. if (file.isDirectory()) {
  271. // Drives
  272. if (file.getParentFile() == null) {
  273. return "inode/drive";
  274. } else {
  275. return "inode/directory";
  276. }
  277. }
  278. // Return type from extension
  279. return getMIMEType(file.getName());
  280. }
  281. /**
  282. * Adds a mime-type mapping for the given filename extension. If the
  283. * extension is already in the internal mapping it is overwritten.
  284. *
  285. * @param extension
  286. * the filename extension to be associated with
  287. * <code>MIMEType</code>.
  288. * @param mimeType
  289. * the new mime-type for <code>extension</code>.
  290. */
  291. public static void addExtension(String extension, String mimeType) {
  292. EXT_TO_MIME_MAP.put(extension.toLowerCase(Locale.ROOT), mimeType);
  293. }
  294. /**
  295. * Gets the internal file extension to mime-type mapping.
  296. *
  297. * @return unmodifiable map containing the current file extension to
  298. * mime-type mapping
  299. */
  300. public static Map<String, String> getExtensionToMIMETypeMapping() {
  301. return Collections.unmodifiableMap(EXT_TO_MIME_MAP);
  302. }
  303. protected FileTypeResolver() {
  304. }
  305. }