MediaTypes.kt
package com.hexagonkt.core.media
import com.hexagonkt.core.media.MediaTypeGroup.*
import java.io.File
import java.net.URI
import java.net.URL
import java.nio.file.Path
import kotlin.io.path.extension
val MEDIA_TYPE_FORMAT: Regex by lazy { """\*|([\w+.-]+)""".toRegex() }
val ANY_MEDIA: MediaType by lazy { MediaType(ANY, "*") }
val APPLICATION_AVRO: MediaType by lazy { MediaType(APPLICATION, "avro") }
val APPLICATION_CBOR: MediaType by lazy { MediaType(APPLICATION, "cbor") }
val APPLICATION_JSON: MediaType by lazy { MediaType(APPLICATION, "json") }
val APPLICATION_YAML: MediaType by lazy { MediaType(APPLICATION, "yaml") }
val APPLICATION_XML: MediaType by lazy { MediaType(APPLICATION, "xml") }
val APPLICATION_GZIP: MediaType by lazy { MediaType(APPLICATION, "gzip") }
val APPLICATION_COMPRESS: MediaType by lazy { MediaType(APPLICATION, "compress") }
val APPLICATION_OCTET_STREAM: MediaType by lazy { MediaType(APPLICATION, "octet-stream") }
val APPLICATION_PDF: MediaType by lazy { MediaType(APPLICATION, "pdf") }
val APPLICATION_POSTSCRIPT: MediaType by lazy { MediaType(APPLICATION, "postscript") }
val APPLICATION_RTF: MediaType by lazy { MediaType(APPLICATION, "rtf") }
val APPLICATION_X_CSH: MediaType by lazy { MediaType(APPLICATION, "x-csh") }
val APPLICATION_X_GTAR: MediaType by lazy { MediaType(APPLICATION, "x-gtar") }
val APPLICATION_X_LATEX: MediaType by lazy { MediaType(APPLICATION, "x-latex") }
val APPLICATION_X_SH: MediaType by lazy { MediaType(APPLICATION, "x-sh") }
val APPLICATION_X_TAR: MediaType by lazy { MediaType(APPLICATION, "x-tar") }
val APPLICATION_X_TCL: MediaType by lazy { MediaType(APPLICATION, "x-tcl") }
val APPLICATION_X_TEX: MediaType by lazy { MediaType(APPLICATION, "x-tex") }
val APPLICATION_X_TEXINFO: MediaType by lazy { MediaType(APPLICATION, "x-texinfo") }
val APPLICATION_ZIP: MediaType by lazy { MediaType(APPLICATION, "zip") }
val APPLICATION_EPUB_ZIP: MediaType by lazy { MediaType(APPLICATION, "epub+zip") }
val APPLICATION_JAVA_ARCHIVE: MediaType by lazy { MediaType(APPLICATION, "java-archive") }
val APPLICATION_OGG: MediaType by lazy { MediaType(APPLICATION, "ogg") }
val APPLICATION_RAR: MediaType by lazy { MediaType(APPLICATION, "vnd.rar") }
val APPLICATION_XHTML: MediaType by lazy { MediaType(APPLICATION, "xhtml+xml") }
val APPLICATION_WEB_MANIFEST: MediaType by lazy { MediaType(APPLICATION, "manifest+json") }
val APPLICATION_TOML: MediaType by lazy { MediaType(APPLICATION, "toml") }
val APPLICATION_7Z: MediaType by lazy { MediaType(APPLICATION, "x-7z-compressed") }
val APPLICATION_BZIP: MediaType by lazy { MediaType(APPLICATION, "x-bzip") }
val APPLICATION_BZIP2: MediaType by lazy { MediaType(APPLICATION, "x-bzip2") }
val APPLICATION_CDF: MediaType by lazy { MediaType(APPLICATION, "x-cdf") }
val APPLICATION_PHP: MediaType by lazy { MediaType(APPLICATION, "x-httpd-php") }
val AUDIO_BASIC: MediaType by lazy { MediaType(AUDIO, "basic") }
val AUDIO_MPEG: MediaType by lazy { MediaType(AUDIO, "mpeg") }
val AUDIO_WAV: MediaType by lazy { MediaType(AUDIO, "wav") }
val AUDIO_AAC: MediaType by lazy { MediaType(AUDIO, "aac") }
val AUDIO_MIDI: MediaType by lazy { MediaType(AUDIO, "midi") }
val AUDIO_OGG: MediaType by lazy { MediaType(AUDIO, "ogg") }
val AUDIO_OPUS: MediaType by lazy { MediaType(AUDIO, "opus") }
val AUDIO_WEBM: MediaType by lazy { MediaType(AUDIO, "webm") }
val FONT_OTF: MediaType by lazy { MediaType(FONT, "otf") }
val FONT_TTF: MediaType by lazy { MediaType(FONT, "ttf") }
val FONT_WOFF: MediaType by lazy { MediaType(FONT, "woff") }
val FONT_WOFF2: MediaType by lazy { MediaType(FONT, "woff2") }
val IMAGE_GIF: MediaType by lazy { MediaType(IMAGE, "gif") }
val IMAGE_JPEG: MediaType by lazy { MediaType(IMAGE, "jpeg") }
val IMAGE_PNG: MediaType by lazy { MediaType(IMAGE, "png") }
val IMAGE_TIFF: MediaType by lazy { MediaType(IMAGE, "tiff") }
val IMAGE_SVG: MediaType by lazy { MediaType(IMAGE, "svg+xml") }
val IMAGE_ICO: MediaType by lazy { MediaType(IMAGE, "vnd.microsoft.icon") }
val IMAGE_WEBP: MediaType by lazy { MediaType(IMAGE, "webp") }
val IMAGE_AVIF: MediaType by lazy { MediaType(IMAGE, "avif") }
val MULTIPART_ALTERNATIVE: MediaType by lazy { MediaType(MULTIPART, "alternative") }
val MULTIPART_APPLEDOUBLE: MediaType by lazy { MediaType(MULTIPART, "appledouble") }
val MULTIPART_DIGEST: MediaType by lazy { MediaType(MULTIPART, "digest") }
val MULTIPART_MIXED: MediaType by lazy { MediaType(MULTIPART, "mixed") }
val MULTIPART_PARALLEL: MediaType by lazy { MediaType(MULTIPART, "parallel") }
val TEXT_CSV: MediaType by lazy { MediaType(TEXT, "csv") }
val TEXT_X_JAVA_PROPERTIES: MediaType by lazy { MediaType(TEXT, "x-java-properties") }
val TEXT_JAVASCRIPT: MediaType by lazy { MediaType(TEXT, "javascript") }
val TEXT_CSS: MediaType by lazy { MediaType(TEXT, "css") }
val TEXT_HTML: MediaType by lazy { MediaType(TEXT, "html") }
val TEXT_MARKDOWN: MediaType by lazy { MediaType(TEXT, "markdown") }
val TEXT_PLAIN: MediaType by lazy { MediaType(TEXT, "plain") }
val TEXT_RICHTEXT: MediaType by lazy { MediaType(TEXT, "richtext") }
val TEXT_TAB_SEPARATED_VALUES: MediaType by lazy { MediaType(TEXT, "tab-separated-values") }
val TEXT_CALENDAR: MediaType by lazy { MediaType(TEXT, "calendar") }
val TEXT_EVENT_STREAM: MediaType by lazy { MediaType(TEXT, "event-stream") }
val VIDEO_MPEG: MediaType by lazy { MediaType(VIDEO, "mpeg") }
val VIDEO_QUICKTIME: MediaType by lazy { MediaType(VIDEO, "quicktime") }
val VIDEO_X_MSVIDEO: MediaType by lazy { MediaType(VIDEO, "x-msvideo") }
val VIDEO_MP4: MediaType by lazy { MediaType(VIDEO, "mp4") }
val VIDEO_OGG: MediaType by lazy { MediaType(VIDEO, "ogg") }
val VIDEO_WEBM: MediaType by lazy { MediaType(VIDEO, "webm") }
val DEFAULT_MEDIA_TYPE: MediaType by lazy { APPLICATION_OCTET_STREAM }
internal val MEDIA_TYPES_EXTENSIONS: Map<String, MediaType> by lazy {
mapOf(
"avro" to APPLICATION_AVRO,
"cbor" to APPLICATION_CBOR,
"json" to APPLICATION_JSON,
"yaml" to APPLICATION_YAML,
"yml" to APPLICATION_YAML,
"xml" to APPLICATION_XML,
"bin" to APPLICATION_OCTET_STREAM,
"lha" to APPLICATION_OCTET_STREAM,
"lzh" to APPLICATION_OCTET_STREAM,
"exe" to APPLICATION_OCTET_STREAM,
"so" to APPLICATION_OCTET_STREAM,
"class" to APPLICATION_OCTET_STREAM,
"pdf" to APPLICATION_PDF,
"ai" to APPLICATION_POSTSCRIPT,
"eps" to APPLICATION_POSTSCRIPT,
"ps" to APPLICATION_POSTSCRIPT,
"rtf" to APPLICATION_RTF,
"z" to APPLICATION_COMPRESS,
"csh" to APPLICATION_X_CSH,
"gtar" to APPLICATION_X_GTAR,
"gz" to APPLICATION_GZIP,
"gzip" to APPLICATION_GZIP,
"latex" to APPLICATION_X_LATEX,
"sh" to APPLICATION_X_SH,
"tar" to APPLICATION_X_TAR,
"tcl" to APPLICATION_X_TCL,
"tex" to APPLICATION_X_TEX,
"texinfo" to APPLICATION_X_TEXINFO,
"texi" to APPLICATION_X_TEXINFO,
"zip" to APPLICATION_ZIP,
"epub" to APPLICATION_EPUB_ZIP,
"jar" to APPLICATION_JAVA_ARCHIVE,
"ogx" to APPLICATION_OGG,
"rar" to APPLICATION_RAR,
"7z" to APPLICATION_7Z,
"bz" to APPLICATION_BZIP,
"bz2" to APPLICATION_BZIP2,
"cda" to APPLICATION_CDF,
"php" to APPLICATION_PHP,
"xhtml" to APPLICATION_XHTML,
"webmanifest" to APPLICATION_WEB_MANIFEST,
"toml" to APPLICATION_TOML,
"au" to AUDIO_BASIC,
"snd" to AUDIO_BASIC,
"mpga" to AUDIO_MPEG,
"mp2" to AUDIO_MPEG,
"mp2a" to AUDIO_MPEG,
"mp3" to AUDIO_MPEG,
"m2a" to AUDIO_MPEG,
"m3a" to AUDIO_MPEG,
"wav" to AUDIO_WAV,
"aac" to AUDIO_AAC,
"mid" to AUDIO_MIDI,
"midi" to AUDIO_MIDI,
"oga" to AUDIO_OGG,
"opus" to AUDIO_OPUS,
"weba" to AUDIO_WEBM,
"otf" to FONT_OTF,
"ttf" to FONT_TTF,
"woff" to FONT_WOFF,
"woff2" to FONT_WOFF2,
"gif" to IMAGE_GIF,
"jpeg" to IMAGE_JPEG,
"jpg" to IMAGE_JPEG,
"png" to IMAGE_PNG,
"tiff" to IMAGE_TIFF,
"tif" to IMAGE_TIFF,
"svg" to IMAGE_SVG,
"ico" to IMAGE_ICO,
"webp" to IMAGE_WEBP,
"avif" to IMAGE_AVIF,
"csv" to TEXT_CSV,
"properties" to TEXT_X_JAVA_PROPERTIES,
"js" to TEXT_JAVASCRIPT,
"css" to TEXT_CSS,
"html" to TEXT_HTML,
"htm" to TEXT_HTML,
"md" to TEXT_MARKDOWN,
"txt" to TEXT_PLAIN,
"log" to TEXT_PLAIN,
"rtx" to TEXT_RICHTEXT,
"tsv" to TEXT_TAB_SEPARATED_VALUES,
"ics" to TEXT_CALENDAR,
"mpeg" to VIDEO_MPEG,
"mpg" to VIDEO_MPEG,
"mpe" to VIDEO_MPEG,
"m1v" to VIDEO_MPEG,
"m2v" to VIDEO_MPEG,
"qt" to VIDEO_QUICKTIME,
"mov" to VIDEO_QUICKTIME,
"avi" to VIDEO_X_MSVIDEO,
"mp4" to VIDEO_MP4,
"ogv" to VIDEO_OGG,
"webm" to VIDEO_WEBM,
)
}
internal val EXTENSIONS_BY_MEDIA: Map<MediaType, List<String>> by lazy {
MEDIA_TYPES_EXTENSIONS.entries
.groupBy { it.value }
.mapValues {
it.value.map { entry -> entry.key }
}
}
fun parseMediaType(fullType: String): MediaType {
val groupType = fullType.split("/")
require(groupType.size == 2) { "Media type format must be <type>/<subtype>: $fullType" }
val groupText = groupType.first().uppercase()
val group = if (groupText == "*") ANY else MediaTypeGroup.valueOf(groupText)
val type = groupType.last()
return MediaType(group, type)
}
fun mediaTypeOfOrNull(uri: URI): MediaType? =
mediaTypeOfOrNull(pathExtension(uri.path))
fun mediaTypeOfOrNull(url: URL): MediaType? =
mediaTypeOfOrNull(pathExtension(url.file))
fun mediaTypeOfOrNull(file: File): MediaType? =
mediaTypeOfOrNull(file.extension)
fun mediaTypeOfOrNull(path: Path): MediaType? =
mediaTypeOfOrNull(path.extension)
fun mediaTypeOfOrNull(extension: String): MediaType? =
MEDIA_TYPES_EXTENSIONS[extension]
fun mediaTypeOf(uri: URI): MediaType =
mediaTypeOfOrNull(uri) ?: error("Media type not found for: '$uri' URI")
fun mediaTypeOf(url: URL): MediaType =
mediaTypeOfOrNull(url) ?: error("Media type not found for: '$url' URL")
fun mediaTypeOf(file: File): MediaType =
mediaTypeOfOrNull(file) ?: error("Media type not found for: '$file' file")
fun mediaTypeOf(path: Path): MediaType =
mediaTypeOfOrNull(path) ?: error("Media type not found for: '$path' path")
fun mediaTypeOf(extension: String): MediaType =
mediaTypeOfOrNull(extension) ?: error("Media type not found for: '$extension' extension")
fun extensionsOf(mediaType: MediaType): List<String> =
EXTENSIONS_BY_MEDIA[mediaType] ?: emptyList()
fun pathExtension(path: String): String =
path.substringAfterLast('.')