2121import static com .google .common .base .Preconditions .checkArgument ;
2222import static java .util .Objects .requireNonNull ;
2323
24+ import java .io .File ;
25+ import java .nio .file .Path ;
2426import java .util .ArrayList ;
2527import java .util .Collections ;
2628import java .util .LinkedHashMap ;
3335
3436import com .google .common .collect .ImmutableList ;
3537import com .google .common .collect .ImmutableMap ;
38+ import com .typesafe .config .Config ;
39+ import com .typesafe .config .ConfigFactory ;
3640
3741/**
3842 * An immutable implementation of HTTP media types (a.k.a mime types).
@@ -302,6 +306,10 @@ private MediaType doFirst(final List<MediaType> candidates) {
302306 .put ("*" , all )
303307 .build ();
304308
309+ static final Config types = ConfigFactory
310+ .parseResources ("mime.properties" )
311+ .withFallback (ConfigFactory .parseResources (MediaType .class , "mime.properties" ));
312+
305313 /**
306314 * Creates a new {@link MediaType}.
307315 *
@@ -541,4 +549,57 @@ public static Matcher matcher(final @Nonnull List<MediaType> acceptable) {
541549 return new Matcher (acceptable );
542550 }
543551
544- }
552+ /**
553+ * Get a {@link MediaType} for a file.
554+ *
555+ * @param file A candidate file.
556+ * @return A {@link MediaType} or {@link MediaType#octetstream} for unknown file extensions.
557+ */
558+ public static @ Nonnull Optional <MediaType > byFile (@ Nonnull final File file ) {
559+ requireNonNull (file , "A file is required." );
560+ return byPath (file .getAbsolutePath ());
561+ }
562+
563+ /**
564+ * Get a {@link MediaType} for a file path.
565+ *
566+ * @param path A candidate file path.
567+ * @return A {@link MediaType} or empty optional for unknown file extensions.
568+ */
569+ public static Optional <MediaType > byPath (final Path path ) {
570+ requireNonNull (path , "A path is required." );
571+ return byPath (path .toString ());
572+ }
573+
574+ /**
575+ * Get a {@link MediaType} for a file path.
576+ *
577+ * @param path A candidate file path: like <code>myfile.js</code> or <code>/js/myfile.js</code>.
578+ * @return A {@link MediaType} or empty optional for unknown file extensions.
579+ */
580+ public static Optional <MediaType > byPath (final String path ) {
581+ requireNonNull (path , "A path is required." );
582+ int idx = path .lastIndexOf ('.' );
583+ if (idx != -1 ) {
584+ String ext = path .substring (idx + 1 );
585+ return byExtension (ext );
586+ }
587+ return Optional .empty ();
588+ }
589+
590+ /**
591+ * Get a {@link MediaType} for a file extension.
592+ *
593+ * @param ext A file extension, like <code>js</code> or <code>css</code>.
594+ * @return A {@link MediaType} or empty optional for unknown file extensions.
595+ */
596+ public static @ Nonnull Optional <MediaType > byExtension (final String ext ) {
597+ requireNonNull (ext , "An ext is required." );
598+ String key = "mime." + ext ;
599+ if (types .hasPath (key )) {
600+ return Optional .of (MediaType .valueOf (types .getString ("mime." + ext )));
601+ }
602+ return Optional .empty ();
603+ }
604+
605+ }
0 commit comments