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 18KB

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