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

com.greenfossil.thorium.MultipartFormData.scala Maven / Gradle / Ivy

/*
 * Copyright 2022 Greenfossil Pte Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.greenfossil.thorium

import com.linecorp.armeria.common.MediaType
import com.linecorp.armeria.common.multipart.{AggregatedBodyPart, AggregatedMultipart, MultipartFile}

import java.io.{File, InputStream}
import java.nio.charset.Charset
import java.nio.file.*
import scala.util.Try

case class MultipartFormData(aggMultipart: AggregatedMultipart, multipartUploadLocation: Path):
  import scala.jdk.CollectionConverters.*

  lazy val bodyPart: Seq[AggregatedBodyPart] = aggMultipart.bodyParts().asScala.toSeq

  lazy val names: List[String] = aggMultipart.names().asScala.toList

  lazy val asFormUrlEncoded: FormUrlEndcoded =
    val xs = for {
      name <- names
      part <- aggMultipart.fields(name).asScala
      content =
        if part.contentType().is(MediaType.PLAIN_TEXT) then
          part.content(Option(part.contentType().charset()).getOrElse(Charset.forName("UTF-8")))
        else if part.filename() != null then
          part.filename()
        else null
      if content != null
    } yield
      (name, content)
    FormUrlEndcoded(xs.groupMap(_._1)(_._2))

  private def saveFileTo( part: AggregatedBodyPart): Option[File] =
    Try {
      if !Files.exists(multipartUploadLocation) then multipartUploadLocation.toFile.mkdirs()
      val filePath = multipartUploadLocation.resolve(part.filename())
      val is: InputStream = part.content().toInputStream
      Files.copy(is, filePath, StandardCopyOption.REPLACE_EXISTING)
      is.close()
      filePath.toFile
    }.toOption

  lazy val files: List[MultipartFile] =
    for {
      name <- names
      part <- aggMultipart.fields(name).asScala
      if part.filename() != null && !part.content().isEmpty
      file <- saveFileTo(part)
    } yield  MultipartFile.of(name, part.filename(), file)

  /**
   * Find a file using the form name
   * @param formNameRegex - this is the alias of findFileOfFormName
   * @return
   */
  def findFile(formNameRegex: String): Option[MultipartFile] =
    findFileOfFormName(formNameRegex)

  /**
   * Find a file using the form name
   * @param formNameRegex
   * @return
   */
  def findFileOfFormName(formNameRegex: String): Option[MultipartFile] =
    files.find(file => file.name.matches(formNameRegex) && file.file().length() > 0)

  /**
   * Find a file using the actual loaded filename
   * @param fileNameRegex
   * @return
   */
  def findFileOfFileName(fileNameRegex: String): Option[MultipartFile] =
    files.find(file => file.filename().matches(fileNameRegex) && file.file().length() > 0)




© 2015 - 2024 Weber Informatics LLC | Privacy Policy