<commit_before>/*
* Copyright 2007-2008 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.http

import scala.actors.Actor
import scala.actors.Actor._
import javax.servlet.http.{HttpSessionBindingListener, HttpSessionBindingEvent, HttpSession}
import scala.collection.mutable.{HashMap, ArrayBuffer, ListBuffer}
import scala.xml.{NodeSeq, Unparsed, Text}
import net.liftweb.mapper.DB
import net.liftweb.util._
import net.liftweb.util.Helpers._
import java.lang.reflect.{Method, Modifier, InvocationTargetException}
import scala.xml.{Node, NodeSeq, Elem, MetaData, Null, UnprefixedAttribute, PrefixedAttribute, XML, Comment, Group}
import java.io.InputStream
import javax.servlet.http.{HttpSessionActivationListener, HttpSessionEvent, HttpServletRequest}
import scala.xml.transform._

object LiftSession {

  def createSession(session: HttpSession,  contextPath: String) = (new LiftSession(contextPath)).setSession(session)

  var creator = createSession _

  def apply(session: HttpSession, contextPath: String) =
  creator(session, contextPath)
}


private[http] case class AddSession(session: LiftSession)
private[http] case class RemoveSession(session: LiftSession)
private[http] object CheckAndPurge

object SessionMaster extends Actor {
  private var sessions: Map[String, LiftSession] = Map.empty
  
  def act = loop {
    react {
      case AddSession(session) => 
      sessions = sessions + ( (session.uniqueId -> session) )
      
      case RemoveSession(session) =>
      sessions = sessions - session.uniqueId
      
      case CheckAndPurge =>
      val now = millis
      for ((id, session) <- sessions.elements) {
        if (now - session.lastServiceTime > session.inactivityLength) {
          Log.info(" Session "+id+" expired")
          session.httpSession.invalidate
        }
      }
      doPing()
      
    }
  }
  
  this.start
  
  def doPing() {
    try {
      ActorPing.schedule(this, CheckAndPurge, 10000L)
    } catch {
      case e => Log.error("Couldn't start SessionMaster ping", e)
    }
  }
  
  doPing()
}

@serializable
class LiftSession( val contextPath: String) extends /*Actor with */ HttpSessionBindingListener with HttpSessionActivationListener {
  import TemplateFinder._

  private var running_? = false
  
  private var messageCallback: HashMap[String, S.AFuncHolder] = new HashMap
  
  private[http] var notices: Seq[(NoticeType.Value, NodeSeq, Can[String])] = Nil
  //  private var _state: Map[String, String] = Map.empty
  
  private var asyncComponents = new HashMap[(Can[String], Can[String]), CometActor]()
  
  private var asyncById = new HashMap[String, CometActor]()

  val uniqueId = "LiftSession_"+randomString(20)

  @transient
  private[http] var httpSession: HttpSession = _
  
  @volatile
  private[http] var lastServiceTime = millis
  
  @volatile
  private[http] var inactivityLength = 180000L

  def sessionDidActivate(se: HttpSessionEvent) = {
    this.setSession(se.getSession)<commit_msg>Cleanup of SessionMaster<commit_after>/*
* Copyright 2007-2008 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.http

import scala.actors.Actor
import scala.actors.Actor._
import javax.servlet.http.{HttpSessionBindingListener, HttpSessionBindingEvent, HttpSession}
import scala.collection.mutable.{HashMap, ArrayBuffer, ListBuffer}
import scala.xml.{NodeSeq, Unparsed, Text}
import net.liftweb.mapper.DB
import net.liftweb.util._
import net.liftweb.util.Helpers._
import java.lang.reflect.{Method, Modifier, InvocationTargetException}
import scala.xml.{Node, NodeSeq, Elem, MetaData, Null, UnprefixedAttribute, PrefixedAttribute, XML, Comment, Group}
import java.io.InputStream
import javax.servlet.http.{HttpSessionActivationListener, HttpSessionEvent, HttpServletRequest}
import scala.xml.transform._

object LiftSession {

  def createSession(session: HttpSession,  contextPath: String) = (new LiftSession(contextPath)).setSession(session)

  var creator = createSession _

  def apply(session: HttpSession, contextPath: String) =
  creator(session, contextPath)
}


private[http] case class AddSession(session: LiftSession)
private[http] case class RemoveSession(session: LiftSession)

/**
* Manages LiftSessions because the servlet container is less than optimal at
* timing sessions out.
*/
object SessionMaster extends Actor {
  private var sessions: Map[String, LiftSession] = Map.empty
  private object CheckAndPurge
  
  def act = {
    doPing()
    loop {
      react {
        case AddSession(session) => 
        sessions = sessions + ( (session.uniqueId -> session) )
        
        case RemoveSession(session) =>
        sessions = sessions - session.uniqueId
        
        case CheckAndPurge =>
        val now = millis
        for ((id, session) <- sessions.elements) {
          if (now - session.lastServiceTime > session.inactivityLength) {
            Log.info(" Session "+id+" expired")
            session.httpSession.invalidate
          }
        }
        doPing()
        
      }
    }
  }
  
  this.start
  
  def doPing() {
    try {
      ActorPing.schedule(this, CheckAndPurge, 10000L)
    } catch {
      case e => Log.error("Couldn't start SessionMaster ping", e)
    }
  }
  
  
}

@serializable
class LiftSession( val contextPath: String) extends /*Actor with */ HttpSessionBindingListener with HttpSessionActivationListener {
  import TemplateFinder._

  private var running_? = false
  
  private var messageCallback: HashMap[String, S.AFuncHolder] = new HashMap
  
  private[http] var notices: Seq[(NoticeType.Value, NodeSeq, Can[String])] = Nil
  //  private var _state: Map[String, String] = Map.empty
  
  private var asyncComponents = new HashMap[(Can[String], Can[String]), CometActor]()
  
  private var asyncById = new HashMap[String, CometActor]()

  val uniqueId = "LiftSession_"+randomString(20)

  @transient
  private[http] var httpSession: HttpSession = _
  
  @volatile
  private[http] var lastServiceTime = millis
  
  @volatile
  private[http] var inactivityLength = 180000L

  def sessionDidActivate(se: HttpSessionEvent) = {
    this.setSession(se.getSession)
{'fraction_non_alphanumeric': 0.09317896498814339, 'fraction_numerical': 0.006974473427256242, 'mean_word_length': 3.9075975359342916, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 6}, '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': '4039458', 'n_tokens_mistral': 2137, 'n_tokens_neox': 2051, 'n_words': 607}