All Downloads are FREE. Search and download functionalities are using the official Maven repository.

skinny.micro.Mimes.scala Maven / Gradle / Ivy

The newest version!
package skinny.micro

import java.io.{ File, InputStream }
import java.net.{ URI, URL }

import eu.medsea.mimeutil.{ MimeType, MimeUtil2 }
import eu.medsea.util.EncodingGuesser
import skinny.logging.Logger

import scala.collection.JavaConverters._
import scala.util.control.Exception._

import Mimes._

/**
 * A utility to help with mime type detection for a given file path or url
 */
trait Mimes {

  @transient private[this] val internalLogger = Logger(getClass)

  protected[this] def mimeUtil: MimeUtil2 = new MimeUtil2()
  quiet { mimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.MagicMimeMimeDetector") }
  quiet { mimeUtil.registerMimeDetector("eu.medsea.mimeutil.detector.ExtensionMimeDetector") }

  def bytesMime(content: Array[Byte], fallback: String = DefaultMime): String = {
    detectMime(fallback) {
      MimeUtil2.getMostSpecificMimeType(mimeUtil.getMimeTypes(content, new MimeType(fallback))).toString
    }
  }
  def fileMime(file: File, fallback: String = DefaultMime): String = {
    detectMime(fallback) {
      MimeUtil2.getMostSpecificMimeType(mimeUtil.getMimeTypes(file, new MimeType(fallback))).toString
    }
  }
  def inputStreamMime(input: InputStream, fallback: String = DefaultMime): String = {
    detectMime(fallback) {
      MimeUtil2.getMostSpecificMimeType(mimeUtil.getMimeTypes(input, new MimeType(fallback))).toString
    }
  }

  /**
   * Detects the mime type of a given file path.
   *
   * @param path The path for which to detect the mime type
   * @param fallback A fallback value in case no mime type can be found
   */
  def mimeType(path: String, fallback: String = DefaultMime): String = {
    detectMime(fallback) {
      MimeUtil2.getMostSpecificMimeType(mimeUtil.getMimeTypes(path, new MimeType(fallback))).toString
    }
  }

  /**
   * Detects the mime type of a given url.
   *
   * @param url The url for which to detect the mime type
   * @param fallback A fallback value in case no mime type can be found
   */
  def urlMime(url: String, fallback: String = DefaultMime): String = {
    detectMime(fallback) {
      MimeUtil2.getMostSpecificMimeType(
        mimeUtil.getMimeTypes(new URL(url), new MimeType(fallback))).toString
    }
  }

  private def detectMime(fallback: String = DefaultMime)(mimeDetect: => String): String = {
    def errorHandler(t: Throwable) = {
      internalLogger.warn("There was an error detecting the mime type. ", t)
      fallback
    }
    allCatch.withApply(errorHandler)(mimeDetect)
  }

  def isTextMime(mime: String): Boolean = MimeUtil2.isTextMimeType(new MimeType(mime))

  private def quiet(fn: => Unit): Unit = {
    allCatch.withApply(
      internalLogger.warn("An error occurred while registering a mime type detector.", _))(fn)
  }

  def apply(input: InputStream) = inputStreamMime(input)
  def apply(file: File) = fileMime(file)
  def apply(bytes: Array[Byte]) = bytesMime(bytes)
  def apply(uri: URI) = urlMime(uri.toASCIIString)

}

object Mimes {

  val DefaultMime = "application/octet-stream"
  /**
   * Sets supported encodings for the mime-util library if they have not been
   * set. Since the supported encodings is stored as a static Set we
   * synchronize access.
   */
  private def registerEncodingsIfNotSet(): Unit = {
    synchronized {
      if (EncodingGuesser.getSupportedEncodings.isEmpty) {
        val enc = Set(
          "UTF-8",
          "ISO-8859-1",
          "windows-1252",
          "MacRoman",
          EncodingGuesser.getDefaultEncoding)
        EncodingGuesser.setSupportedEncodings(enc.asJava)
      }
    }
  }
  registerEncodingsIfNotSet
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy