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

net.twibs.web.Response.scala Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2013-2015 by Michael Hombre Brinkmann
 */

package net.twibs.web

import com.google.common.base.Charsets
import com.google.common.io.{CharStreams, ByteStreams}
import concurrent.duration._
import java.io._
import java.util.zip.GZIPOutputStream
import net.twibs.util.Predef._
import net.twibs.util.{ApplicationSettings, RunMode}

import scala.language.postfixOps

trait Response extends Serializable {
  def asInputStream: InputStream

  def asBytes: Array[Byte]

  def asString: String

  def length: Long

  def lastModified: Long

  def mimeType: String

  def isModified: Boolean

  def isCacheable: Boolean

  def expiresOnClientAfter: Duration

  def isContentFinal: Boolean = false

  def isInMemory: Boolean

  lazy val gzippedOption: Option[Array[Byte]] = {
    val bytes = asInputStream useAndClose compressWithGzip
    if (bytes.length < length) Some(bytes) else None
  }

  private def compressWithGzip(uncompressed: InputStream) = {
    val baos = new ByteArrayOutputStream()
    new GZIPOutputStream(baos) useAndClose {ByteStreams.copy(uncompressed, _)}
    baos.toByteArray
  }

}

trait InputStreamResponse extends Response {
  def asBytes: Array[Byte] = ByteStreams.toByteArray(asInputStream)

  def asString: String = CharStreams.toString(new InputStreamReader(asInputStream, Charsets.UTF_8))

  def isInMemory: Boolean = false
}

trait FileResponse extends InputStreamResponse {
  def file: File

  def asInputStream = new FileInputStream(file)

  val length = file.length()

  val lastModified = file.lastModified()

  def isModified = !file.exists || file.lastModified() != lastModified

  lazy val mimeType = ApplicationSettings.tika.detect(file)
}

trait StringResponse extends Response {
  def asBytes: Array[Byte] = asString.getBytes(Charsets.UTF_8)

  def asInputStream: InputStream = new ByteArrayInputStream(asBytes)

  def length: Long = asBytes.length

  def isInMemory: Boolean = true
}

trait ByteArrayResponse extends Response {
  def asString = new String(asBytes, Charsets.UTF_8)

  def asInputStream: InputStream = new ByteArrayInputStream(asBytes)

  def length: Long = asBytes.length

  def isInMemory: Boolean = true
}

class RedirectResponse(val asString: String) extends StringResponse {
  def lastModified: Long = 0

  def mimeType: String = ""

  def isModified: Boolean = true

  def isCacheable: Boolean = false

  def expiresOnClientAfter = if (RunMode.isDevelopment) 1 seconds else 8 hours

  override def isContentFinal: Boolean = true
}

trait ErrorResponse extends Response

trait NotFoundResponse extends Response

trait CacheableResponse extends Response {
  def isCacheable = true

  def expiresOnClientAfter = if (RunMode.isDevelopment) 1 seconds else 8 hours
}

trait NotCacheableResponse extends Response {
  def isCacheable: Boolean = false

  def expiresOnClientAfter = 0 seconds
}

trait VolatileResponse extends NotCacheableResponse {
  def isModified: Boolean = true

  val lastModified: Long = System.currentTimeMillis()
}

trait CalculatedLastModifiedResponse extends CacheableResponse {
  val lastModified: Long = calculateModified

  def isModified: Boolean = lastModified != calculateModified

  def calculateModified: Long
}

trait CompilationTimeResponse extends CalculatedLastModifiedResponse {
  def calculateModified: Long = compilationTime // if (RunMode.isDevelopment) System.currentTimeMillis() else compilationTime

  def compilationTime: Long
}

trait SingleResponseWrapper extends Response {
  protected def delegatee: Response

  def lastModified: Long = delegatee.lastModified

  def isModified: Boolean = delegatee.isModified

  def expiresOnClientAfter: Duration = delegatee.expiresOnClientAfter

  def isCacheable: Boolean = delegatee.isCacheable

  override def isContentFinal = delegatee.isContentFinal
}

trait MultiResponseWrapper extends Response {
  protected def delegatees: List[Response]

  lazy val lastModified: Long = delegatees.map(_.lastModified).max

  def isModified = delegatees.exists(_.isModified)

  lazy val expiresOnClientAfter = delegatees.map(_.expiresOnClientAfter).min

  lazy val isCacheable = delegatees.forall(_.isCacheable)

  override lazy val isContentFinal = delegatees.forall(_.isContentFinal)
}

class DecoratableResponseWrapper(val delegatee: Response) extends SingleResponseWrapper {
  def asInputStream: InputStream = delegatee.asInputStream

  def asBytes: Array[Byte] = delegatee.asBytes

  def asString: String = delegatee.asString

  def length: Long = delegatee.length

  def mimeType: String = delegatee.mimeType

  def isInMemory = delegatee.isInMemory
}

trait AsAttachment extends Response {
  def attachmentFileName: String
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy