<commit_before>/**
 * Copyright (C) 2010 Orbeon, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the
 * GNU Lesser General Public License as published by the Free Software Foundation; either version
 * 2.1 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 *
 * The full text of the license is available at http://www.gnu.org/copyleft/lesser.html
 */
package org.orbeon.oxf.util

import org.orbeon.datatypes.Mediatype
import org.orbeon.oxf.http.Headers
import org.orbeon.oxf.resources.URLFactory
import org.orbeon.oxf.util.CollectionUtils._
import org.orbeon.oxf.util.PathUtils._
import org.orbeon.oxf.util.StringUtils._
import org.orbeon.oxf.xml.{ForwardingXMLReceiver, ParserConfiguration, XMLParsing}
import org.xml.sax.Attributes

import scala.collection.mutable.ListBuffer

object Mediatypes {

  import Private._

  private val (mappingsByMediatype, mappingsByExtension) = {

    val list = {
      val ch = new MimeTypesContentHandler
      val urlString = "oxf:/oxf/mime-types.xml"
      XMLParsing.inputStreamToSAX(
        inputStream         = URLFactory.createURL(urlString).openStream,
        urlString           = urlString,
        xmlReceiver         = ch,
        parserConfiguration = ParserConfiguration.Plain,
        handleLexical       = false,
        resolver            = null
      )
      ch.resultAsList
    }

    (
      combineValues[String, Mapping, List](list map { case m @ Mapping(_, mediatype) => mediatype   -> m }).toMap,
      combineValues[String, Mapping, List](list map { case m @ Mapping(_, _)         => m.extension -> m }).toMap
    )
  }

  def findMediatypeForExtension(extension: String): Option[String] =
    for {
      mappings <- mappingsByExtension.get(extension.toLowerCase)
      mapping  <- mappings.headOption
    } yield
      mapping.mediatype

  def findMediatypeForPath(path: String): Option[String] =
    for {
      extension <- findExtension(path.toLowerCase)
      mediatype <- findMediatypeForExtension(extension)
    } yield
      mediatype

  def findMediatypeForPathJava(path: String): String =
    findMediatypeForPath(path).orNull

  def findExtensionForMediatype(mediatype: String): Option[String] =
    for {
      mappings  <- mappingsByMediatype.get(mediatype)
      mapping   <- mappings.headOption
    } yield
      mapping.extension

  def fromHeadersOrFilename(
    header  : String => Option[String],
    filename: => Option[String]
  ): Option[Mediatype] = {

    def fromHeaders =
      header(Headers.ContentType)            flatMap
        ContentTypes.getContentTypeMediaType filterNot
        (_ == ContentTypes.OctetStreamContentType)

    def fromFilename =
      filename flatMap findMediatypeForPath

    fromHeaders orElse fromFilename flatMap Mediatype.unapply
  }

  private object Private {

    class MimeTypesContentHandler extends ForwardingXMLReceiver {

      import MimeTypesContentHandler._

      private val builder = new java.lang.StringBuilder

      private var state: State = DefaultState
      private var name: String = null

      private var buffer = ListBuffer[Mapping]()

      def resultAsList: List[Mapping] = buffer.result()

      private def extensionFromPattern(pattern: String) =
        pattern.toLowerCase.trimAllToOpt flatMap findExtension getOrElse ""

      override def startElement(uri: String, localname: String, qName: String, attributes: Attributes): Unit =
        localname match {
          case NameElement    => state = NameState<commit_msg>Minor: `val`<commit_after>/**
 * Copyright (C) 2010 Orbeon, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the
 * GNU Lesser General Public License as published by the Free Software Foundation; either version
 * 2.1 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Lesser General Public License for more details.
 *
 * The full text of the license is available at http://www.gnu.org/copyleft/lesser.html
 */
package org.orbeon.oxf.util

import org.orbeon.datatypes.Mediatype
import org.orbeon.oxf.http.Headers
import org.orbeon.oxf.resources.URLFactory
import org.orbeon.oxf.util.CollectionUtils._
import org.orbeon.oxf.util.PathUtils._
import org.orbeon.oxf.util.StringUtils._
import org.orbeon.oxf.xml.{ForwardingXMLReceiver, ParserConfiguration, XMLParsing}
import org.xml.sax.Attributes

import scala.collection.mutable.ListBuffer

object Mediatypes {

  import Private._

  private val (mappingsByMediatype, mappingsByExtension) = {

    val list = {
      val ch = new MimeTypesContentHandler
      val urlString = "oxf:/oxf/mime-types.xml"
      XMLParsing.inputStreamToSAX(
        inputStream         = URLFactory.createURL(urlString).openStream,
        urlString           = urlString,
        xmlReceiver         = ch,
        parserConfiguration = ParserConfiguration.Plain,
        handleLexical       = false,
        resolver            = null
      )
      ch.resultAsList
    }

    (
      combineValues[String, Mapping, List](list map { case m @ Mapping(_, mediatype) => mediatype   -> m }).toMap,
      combineValues[String, Mapping, List](list map { case m @ Mapping(_, _)         => m.extension -> m }).toMap
    )
  }

  def findMediatypeForExtension(extension: String): Option[String] =
    for {
      mappings <- mappingsByExtension.get(extension.toLowerCase)
      mapping  <- mappings.headOption
    } yield
      mapping.mediatype

  def findMediatypeForPath(path: String): Option[String] =
    for {
      extension <- findExtension(path.toLowerCase)
      mediatype <- findMediatypeForExtension(extension)
    } yield
      mediatype

  def findMediatypeForPathJava(path: String): String =
    findMediatypeForPath(path).orNull

  def findExtensionForMediatype(mediatype: String): Option[String] =
    for {
      mappings  <- mappingsByMediatype.get(mediatype)
      mapping   <- mappings.headOption
    } yield
      mapping.extension

  def fromHeadersOrFilename(
    header  : String => Option[String],
    filename: => Option[String]
  ): Option[Mediatype] = {

    def fromHeaders =
      header(Headers.ContentType)            flatMap
        ContentTypes.getContentTypeMediaType filterNot
        (_ == ContentTypes.OctetStreamContentType)

    def fromFilename =
      filename flatMap findMediatypeForPath

    fromHeaders orElse fromFilename flatMap Mediatype.unapply
  }

  private object Private {

    class MimeTypesContentHandler extends ForwardingXMLReceiver {

      import MimeTypesContentHandler._

      private val builder = new java.lang.StringBuilder

      private var state: State = DefaultState
      private var name: String = null

      private val buffer = ListBuffer[Mapping]()

      def resultAsList: List[Mapping] = buffer.result()

      private def extensionFromPattern(pattern: String) =
        pattern.toLowerCase.trimAllToOpt flatMap findExtension getOrElse ""

      override def startElement(uri: String, localname: String, qName: String, attributes: Attributes): Unit =
        localname match {
          case NameElement    => state = NameState
{'fraction_non_alphanumeric': 0.0803960396039604, 'fraction_numerical': 0.0015841584158415843, 'mean_word_length': 3.171806167400881, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 8}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6981745', 'n_tokens_mistral': 2170, 'n_tokens_neox': 2099, 'n_words': 582}