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

net.liftweb.http.provider.servlet.containers.Jetty7AsyncProvider.scala Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2010-2011 WorldWide Conferencing, LLC
 *
 * 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 net.liftweb
package http
package provider
package servlet
package containers

import jakarta.servlet.http.HttpServletRequest

import net.liftweb.common._
import net.liftweb.http._
import net.liftweb.http.provider._
import net.liftweb.http.provider.servlet._
import net.liftweb.util._
import Helpers._


object Jetty7AsyncProvider extends AsyncProviderMeta {
  // contSupport below gets inferred as a Class[?0] existential.
  import scala.language.existentials

  private val (hasContinuations_?,
               contSupport,
               getContinuation,
               getAttribute,
               setAttribute,
               suspendMeth,
               setTimeout,
               resumeMeth,
               isExpired,
               isResumed) = {
    try {
      val cc = Class.forName("org.eclipse.jetty.continuation.ContinuationSupport")
      val meth = cc.getMethod("getContinuation", classOf[jakarta.servlet.ServletRequest])
      val cci = Class.forName("org.eclipse.jetty.continuation.Continuation")
      val getAttribute = cci.getMethod("getAttribute", classOf[String])
      val setAttribute = cci.getMethod("setAttribute", classOf[String], classOf[AnyRef])
      val suspend = cci.getMethod("suspend")
      val setTimeout = cci.getMethod("setTimeout", java.lang.Long.TYPE)
      val resume = cci.getMethod("resume")
      val isExpired = cci.getMethod("isExpired")
      val isResumed = cci.getMethod("isResumed")
      (true, (cc), (meth), (getAttribute), (setAttribute), (suspend), setTimeout, resume, isExpired, isResumed)
    } catch {
      case e: Exception =>
        (false, null, null, null, null, null, null, null, null, null)
    }
  }

  def suspendResumeSupport_? : Boolean = hasContinuations_?


  /**
   * return a function that vends the ServletAsyncProvider
   */
  def providerFunction: Box[HTTPRequest => ServletAsyncProvider] =
    Full(req => new Jetty7AsyncProvider(req)).
  filter(i => suspendResumeSupport_?)
}

/**
 * Jetty7AsyncProvider
 *
 * Implemented by using Jetty 7 Continuation API
 *
 */
class Jetty7AsyncProvider(req: HTTPRequest) extends ServletAsyncProvider {

  import Jetty7AsyncProvider._

  private val servletReq = (req.asInstanceOf[HTTPRequestServlet]).req


  def suspendResumeSupport_? : Boolean = hasContinuations_?

  def resumeInfo: Option[(Req, LiftResponse)] =
    if (!hasContinuations_?) None
    else if (Props.inGAE) None
    else {
      val cont = getContinuation.invoke(contSupport, servletReq)
      val ret = getAttribute.invoke(cont, "__liftCometState")
      try {
        setAttribute.invoke(cont, "__liftCometState", null)
        ret match {
          case (r: Req, lr: LiftResponse) => Some(r -> lr)
          case _ => None
        }
      }
      catch {
        case e: Exception => None
      }
   }

  def suspend(timeout: Long): RetryState.Value = {
    val cont = getContinuation.invoke(contSupport, servletReq)

    val expired = isExpired.invoke(cont).asInstanceOf[Boolean]
    val resumed = isResumed.invoke(cont).asInstanceOf[Boolean]

    if (expired)
      RetryState.TIMED_OUT
    else if (resumed)
      RetryState.RESUMED
    else {
      setTimeout.invoke(cont, new java.lang.Long(timeout))
      suspendMeth.invoke(cont)
      RetryState.SUSPENDED
    }
    
  }

  def resume(what: (Req, LiftResponse)): Boolean = {
    val cont = getContinuation.invoke(contSupport, servletReq)
    try {
      setAttribute.invoke(cont, "__liftCometState", what)
      resumeMeth.invoke(cont)
      true
    } catch {
      case e: Exception => setAttribute.invoke(cont, "__liftCometState", null)
                false
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy