package mycache

import com.opensymphony.oscache.general._
import com.opensymphony.oscache.base.NeedsRefreshException
import java.util.Properties
import java.io.{FileInputStream, File}
import java.util.Date
import org.apache.commons.logging._

/**
 * Singleton que mantem o cache. 
 * OBS: Nao consideradas situacoes de concorrencia.
 */
object object mycache.CacheManagerCacheManager {

  private lazy val org.apache.commons.logging.Loglog = object org.apache.commons.logging.LogFactoryLogFactory.(java.lang.Class[_])org.apache.commons.logging.LoggetLog(()java.lang.Class[_]getClass)
  private val java.util.Propertiesp = java.util.Propertiesnew java.util.PropertiesProperties()
  => java.util.Propertiesp.(java.io.InputStream)Unitload(()java.lang.Class[_]getClass.()java.lang.ClassLoadergetClassLoader.(java.lang.String)java.io.InputStreamgetResourceAsStream(java.lang.String("oscache.properties")"oscache.properties"))

  private val com.opensymphony.oscache.general.GeneralCacheAdministratoradmin = (java.util.Properties)com.opensymphony.oscache.general.GeneralCacheAdministratornew com.opensymphony.oscache.general.GeneralCacheAdministratorGeneralCacheAdministrator(=> java.util.Propertiesp)

  /**
   * Obtem um valor do tipo T com a chave key
   */
  def [T](String)((T) => T)T<<[>: Nothing <: AnyT](Stringkey : StringString)((T) => Trefresher : T => T) : TT = {
    //funcao interna. implicit conversion.
    implicit def [T](java.lang.Object)Tany2T[>: Nothing <: AnyT](java.lang.Objecta : java.lang.ObjectObject) = java.lang.Objecta.TasInstanceOf[TT]
    
    try {
      => org.apache.commons.logging.Loglog (Any)Unitinfo(java.lang.String("###Getting [")"###Getting [" (Any)java.lang.String+ Stringkey (Any)java.lang.String+ java.lang.String("] from cache")"] from cache")
      => com.opensymphony.oscache.general.GeneralCacheAdministratoradmin (java.lang.Object)NothinggetFromCache(Stringkey)
    } catch {
      Tcase com.opensymphony.oscache.base.NeedsRefreshExceptione: com.opensymphony.oscache.base.NeedsRefreshExceptionNeedsRefreshException => 
        => org.apache.commons.logging.Loglog.(Any)Unitwarn(java.lang.String("###No entry found for [")"###No entry found for [" (Any)java.lang.String+ Stringkey (Any)java.lang.String+ java.lang.String("]")"]")
        (String)(=> T)T>> (Stringkey) {
          (T)Trefresher(com.opensymphony.oscache.base.NeedsRefreshExceptione.(java.lang.Object)NothinggetCacheContent)
        }
    }
  }
    
  /**
   * Obtem um valor sem passar um meio de atualizar a 
   * entrada. Caso a entrada nao exista ou precisa ser
   * atualizada, o valor retornado sera null. Caso a entrada
   * exista e necessite atualizacao, o valor retornado sera
   * o stale.
   */
  def [T](String) => T<<-[>: Nothing <: AnyT] = (String)((T) => T)T<<[TT](String_: StringString){Tstale => Tstale}
  
  /**
   * Adiciona uma entrada value com chave key no 
   * chache.
   */
  def [T](String)(=> T)T>>[>: Nothing <: AnyT](Stringkey: StringString)(=> Tvalue : => T) = {

    Unitif (=> Tvalue (Any)Boolean!= Null(null)null) {
      => org.apache.commons.logging.Loglog.(Any)Unitinfo(java.lang.String("###Putting [")"###Putting [" (Any)java.lang.String+ Stringkey (Any)java.lang.String+ java.lang.String("] with ")"] with " (Any)java.lang.String+ => Tvalue)
      => com.opensymphony.oscache.general.GeneralCacheAdministratoradmin.(java.lang.String,Any)UnitputInCache(Stringkey, => Tvalue)
    } else {
      => org.apache.commons.logging.Loglog (Any)Unitwarn(java.lang.String("###Canceling Update. No given refresher/value for [")"###Canceling Update. No given refresher/value for [" (Any)java.lang.String+ Stringkey (Any)java.lang.String+ java.lang.String("]")"]")
      => com.opensymphony.oscache.general.GeneralCacheAdministratoradmin.(java.lang.String)UnitcancelUpdate(Stringkey)
    }
    => org.apache.commons.logging.Loglog (Any)Unitinfo(java.lang.String("Returning [")"Returning [" (Any)java.lang.String+ Stringkey (Any)java.lang.String+ java.lang.String("<-")"<-" (Any)java.lang.String+ => Tvalue (Any)java.lang.String+ java.lang.String("]")"]")
    => Tvalue
  }  
}

object object mycache.MainMain {

  def (Array[String])Unitmain(Array[String]args: Array[String]Array[String])  {
    import CacheManager.{>>, <<, <<-}

    val java.util.Propertiesdb = java.util.Propertiesnew java.util.PropertiesProperties()
    java.util.Propertiesdb.(java.io.InputStream)Unitload(()java.lang.Class[_]getClass.()java.lang.ClassLoadergetClassLoader (java.lang.String)java.io.InputStreamgetResourceAsStream(java.lang.String("db.properties")"db.properties"))

    //get a value an refresh if it does not exist
    val java.lang.StringmyEntry = (String)((java.lang.String) => java.lang.String)java.lang.String<<(java.lang.String("first")"first") {
        Stringstale : StringString => java.lang.Stringif (Stringstale (AnyRef)Boolean== Null(null)null)
                    java.util.Propertiesdb (java.lang.String)java.lang.StringgetProperty java.lang.String("first")"first"
                 else
                    Stringstale
    }
   
    //put a value in cache
    (String)(=> java.util.Date)java.util.Date>>(java.lang.String("birth")"birth")(java.util.Datenew java.util.DateDate())
    val java.util.Datebirth : java.util.DateDate = (String)Nothing<<-(java.lang.String("birth")"birth") 

    // put name -> Igor in cache
    val java.lang.Stringname = (String)(=> java.lang.String)java.lang.String>>(java.lang.String("name")"name") { 
      java.util.Propertiesdb (java.lang.String)java.lang.StringgetProperty(java.lang.String("first")"first")
    }
    
    val Stringaddress = (String)String<<-[StringString](java.lang.String("adress")"adress")
    
    (Any)Unitprintln (java.lang.String("Entry from db: ")"Entry from db: " (Any)java.lang.String+ java.lang.StringmyEntry)
    (Any)Unitprintln (java.lang.String("Now in Cache: ")"Now in Cache: " (Any)java.lang.String+ java.util.Datebirth)
    (Any)Unitprintln (java.lang.String("The Name is: ")"The Name is: " (Any)java.lang.String+ java.lang.Stringname)
    (Any)Unitprintln (java.lang.String("The address: ")"The address: " (Any)java.lang.String+ Stringaddress)
  }
}