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

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