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

net.liftweb.http.provider.servlet.containers.Jetty6AsyncProvider.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 Jetty6AsyncProvider extends AsyncProviderMeta {
  // contSupport below gets inferred as a Class[?0] existential.
  import scala.language.existentials

  private lazy val (hasContinuations_?,
                    contSupport,
                    getContinuation,
                    getObject,
                    setObject,
                    suspendMeth,
                    resumeMeth,
                    isPending) = {
    try {
      val cc = Class.forName("org.mortbay.util.ajax.ContinuationSupport")
      val meth = cc.getMethod("getContinuation", classOf[HttpServletRequest], classOf[AnyRef])
      val cci = Class.forName("org.mortbay.util.ajax.Continuation")
      val getObj = cci.getMethod("getObject")
      val setObj = cci.getMethod("setObject", classOf[AnyRef])
      val suspend = cci.getMethod("suspend", java.lang.Long.TYPE)
      val resume = cci.getMethod("resume")
      val isPending = cci.getMethod("isPending")
      (true, (cc), (meth), (getObj), (setObj), (suspend), resume, isPending)
    } catch {
      case e: Exception => (false, 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 Jetty6AsyncProvider(req)).
  filter(i => suspendResumeSupport_?)


}

/**
 * Jetty6AsyncProvider
 *
 * Implemented by using Jetty 6 Continuation API
 *
 */
class Jetty6AsyncProvider(req: HTTPRequest) extends ServletAsyncProvider with Loggable {

  import Jetty6AsyncProvider._

  private lazy 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, LiftRules)
      val ret = getObject.invoke(cont)
      try {
        setObject.invoke(cont, null)
        ret match {
          case (r: Req, lr: LiftResponse) => Some(r -> lr)
          case _ => None
        }
      }
      catch {
        case e: Exception => None
      }
   }


  def suspend(timeout: Long): RetryState.Value = {
    try {
      val cont = getContinuation.invoke(contSupport, servletReq, LiftRules)
      logger.trace("About to suspend continuation")
      val b = suspendMeth.invoke(cont, new java.lang.Long(timeout)).asInstanceOf[Boolean]
      if (!b) RetryState.TIMED_OUT else RetryState.RESUMED
    } catch {
      case e: java.lang.reflect.InvocationTargetException if e.getCause.getClass.getName.endsWith("RetryRequest") =>
        throw e.getCause
    }
  }

  def resume(what: (Req, LiftResponse)): Boolean = {
    val cont = getContinuation.invoke(contSupport, servletReq, LiftRules)
    cont.synchronized {
      logger.trace("In resume on Jetty 6")
      val pending = isPending.invoke(cont).asInstanceOf[Boolean]
      if (pending) {
       setObject.invoke(cont, what)
       resumeMeth.invoke(cont)
      }
      pending
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy