Package railo.runtime.tag

Source Code of railo.runtime.tag.Cache

package railo.runtime.tag;


import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.http.HttpServletResponse;

import org.apache.oro.text.regex.MalformedPatternException;

import railo.commons.io.IOUtil;
import railo.commons.io.cache.CacheEntry;
import railo.commons.io.res.Resource;
import railo.commons.io.res.util.ResourceUtil;
import railo.commons.lang.StringUtil;
import railo.runtime.PageContextImpl;
import railo.runtime.cache.legacy.CacheItem;
import railo.runtime.config.ConfigImpl;
import railo.runtime.exp.Abort;
import railo.runtime.exp.ApplicationException;
import railo.runtime.exp.DeprecatedException;
import railo.runtime.exp.ExpressionException;
import railo.runtime.exp.PageException;
import railo.runtime.exp.TemplateException;
import railo.runtime.ext.tag.BodyTagImpl;
import railo.runtime.functions.cache.CacheGet;
import railo.runtime.functions.cache.CachePut;
import railo.runtime.functions.cache.CacheRemove;
import railo.runtime.functions.cache.Util;
import railo.runtime.functions.dateTime.GetHttpTimeString;
import railo.runtime.net.http.ReqRspUtil;
import railo.runtime.op.Caster;
import railo.runtime.tag.util.DeprecatedUtil;
import railo.runtime.type.StructImpl;
import railo.runtime.type.dt.DateTime;
import railo.runtime.type.dt.DateTimeImpl;
import railo.runtime.type.dt.TimeSpan;
import railo.runtime.type.dt.TimeSpanImpl;

/**
* Speeds up page rendering when dynamic content does not have to be retrieved each time a user accesses
*   the page. To accomplish this, cfcache creates temporary files that contain the static HTML returned from
*   a CFML page. You can use cfcache for simple URLs and URLs that contain URL parameters.
*
*
*
**/
public final class Cache extends BodyTagImpl {




  private static final TimeSpan TIMESPAN_FAR_AWAY = new TimeSpanImpl(1000000000,1000000000,1000000000,1000000000);
  private static final TimeSpan TIMESPAN_0 = new TimeSpanImpl(0,0,0,0);


  /**  */
  private Resource directory;


  /** Specifies the protocol used to create pages from cache. Either http:// or https://. The default
  **     is http://. */
  private String protocol;

  /**  */
  private String expireurl;

  /**  */
  private int action=CACHE;

  /** When required for basic authentication, a valid username. */
  //private String username;

  /** When required for basic authentication, a valid password. */
  //private String password;
   
  private TimeSpan timespan=TIMESPAN_FAR_AWAY;
  private TimeSpan idletime=TIMESPAN_0;
   

  /**  */
  private int port=-1;

  private DateTimeImpl now;


  private String body;
  private String _id;
  private Object id;
  private String name;
  private String key;


  private boolean hasBody;


  private boolean doCaching;


  private CacheItem cacheItem;


  private String cachename;
  private Object value;
  private boolean throwOnError;
  private String metadata;
   
    private static final int CACHE=0;
    private static final int CACHE_SERVER=1;
    private static final int CACHE_CLIENT=2;
    private static final int FLUSH=3;
    private static final int CONTENT=4;

    private static final int GET=5;
    private static final int PUT=6;
   
    @Override
    public void release()   {
        super.release();
        directory=null;
        //username=null;
        //password=null;
        protocol=null;
        expireurl=null;
        action=CACHE;
        port=-1;
        timespan=TIMESPAN_FAR_AWAY;
        idletime=TIMESPAN_0;
        body=null;
        hasBody=false;
        id=null;
        key=null;
        body=null;
        doCaching=false;
        cacheItem=null;
        name=null;
        cachename=null;
        throwOnError=false;
        value=null;
        metadata=null;
    }
 
  /**
   * @deprecated this attribute is deprecated and will ignored in this tag
   * @param obj
   * @throws DeprecatedException
   */
  public void setTimeout(Object obj) throws DeprecatedException {
    DeprecatedUtil.tagAttribute(pageContext,"Cache","timeout");
  }

  /** set the value directory
  * 
  * @param directory value to set
  **/
  public void setDirectory(String directory) throws ExpressionException  {
    this.directory=ResourceUtil.toResourceExistingParent(pageContext, directory);
  }
  public void setCachedirectory(String directory) throws ExpressionException  {
    setDirectory(directory);
  }
 

  /** set the value protocol
  *  Specifies the protocol used to create pages from cache. Either http:// or https://. The default
  *     is http://.
  * @param protocol value to set
  **/
  public void setProtocol(String protocol)  {
    if(protocol.endsWith("://"))protocol=protocol.substring(0,protocol.indexOf("://"));
    this.protocol=protocol.toLowerCase();
  }
 
  /*private String getProtocol()  {
    if(StringUtil.isEmpty(protocol)) {
      return pageContext. getHttpServletRequest().getScheme();
    }
    return protocol;
  }*/

  /** set the value expireurl
  * 
  * @param expireurl value to set
  **/
  public void setExpireurl(String expireurl)  {
    this.expireurl=expireurl;
  }

  /** set the value action
  * 
  * @param action value to set
   * @throws ApplicationException
  **/
  public void setAction(String action) throws ApplicationException  {
        action=action.toLowerCase().trim();
        if(action.equals("get"))              this.action=GET;
        else if(action.equals("put"))              this.action=PUT;
       
       
        else if(action.equals("cache"))         this.action=CACHE;
        else if(action.equals("clientcache"))   this.action=CACHE_CLIENT;
        else if(action.equals("servercache"))   this.action=CACHE_SERVER;
        else if(action.equals("flush"))         this.action=FLUSH;
        else if(action.equals("optimal"))       this.action=CACHE;
       
        else if(action.equals("client-cache"))   this.action=CACHE_CLIENT;
        else if(action.equals("client_cache"))   this.action=CACHE_CLIENT;
       
        else if(action.equals("server-cache"))   this.action=CACHE_SERVER;
        else if(action.equals("server_cache"))   this.action=CACHE_SERVER;
       
        else if(action.equals("content"))     this.action=CONTENT;
        else if(action.equals("content_cache"))  this.action=CONTENT;
        else if(action.equals("contentcache"))  this.action=CONTENT;
        else if(action.equals("content-cache"))  this.action=CONTENT;
        else throw new ApplicationException("invalid value for attribute action for tag cache ["+action+"], " +
            "valid actions are [get,put,cache, clientcache, servercache, flush, optimal, contentcache]");
       
        //get: get an object from the cache.
        //put: Add an object to the cache.
       

       
       
  }

  /** set the value username
  *  When required for basic authentication, a valid username.
  * @param username value to set
  **/
  public void setUsername(String username)  {
    //this.username=username;
  }
 
  /** set the value password
  *  When required for basic authentication, a valid password.
  * @param password value to set
  **/
  public void setPassword(String password)  {
    //this.password=password;
  }
 
  public void setKey(String key)  {
    this.key=key;
  }

  /** set the value port
  * 
  * @param port value to set
  **/
  public void setPort(double port)  {
    this.port=(int)port;
  }
 
  public int getPort() {
    if(port<=0) return pageContext. getHttpServletRequest().getServerPort();
    return port;
  }

    /**
     * @param timespan The timespan to set.
     * @throws PageException
     */
    public void setTimespan(TimeSpan timespan) {
        this.timespan = timespan;
    }
   
   
    @Override
  public int doStartTag() throws PageException  {
    now = new DateTimeImpl(pageContext.getConfig());
    try {
          if(action==CACHE) {
              doClientCache();
              doServerCache();
          }
          else if(action==CACHE_CLIENTdoClientCache();
          else if(action==CACHE_SERVERdoServerCache();
          else if(action==FLUSH)      doFlush();
          else if(action==CONTENT) return doContentCache();
          else if(action==GET) doGet();
          else if(action==PUT) doPut();
       
      return EVAL_PAGE;
    }
    catch(Exception e) {
      throw Caster.toPageException(e);
    }
  }

  @Override
  public void doInitBody()  {
   
  }

  @Override
  public int doAfterBody()  {
    //print.out("doAfterBody");
    if(bodyContent!=null)body=bodyContent.getString();
    return SKIP_BODY;
  }

    @Override
  public int doEndTag() throws PageException  {//print.out("doEndTag"+doCaching+"-"+body);
    if(doCaching && body!=null) {
        try {
        writeCacheResource(cacheItem, body);
        pageContext.write(body);
      }
        catch (IOException e) {
        throw Caster.toPageException(e);
      }
    }
    return EVAL_PAGE;
  }

  private void doClientCache() {
        pageContext.setHeader("Last-Modified",GetHttpTimeString.call(pageContext,now));
       
        if(timespan!=null) {
            DateTime expires = getExpiresDate();
            pageContext.setHeader("Expires",GetHttpTimeString.call(pageContext,expires));
        }
    }

  private void doServerCache() throws IOException, PageException {
    if(hasBody)hasBody=!StringUtil.isEmpty(body);
   
        // call via cfcache disable debugger output
            if(pageContext.getConfig().debug())pageContext.getDebugger().setOutput(false);
   
        HttpServletResponse rsp = pageContext.getHttpServletResponse();
       
        // generate cache resource matching request object
        CacheItem ci = generateCacheResource(null,false);
       
        // use cached resource
        if(ci.isValid(timespan)){ //if(isOK(cacheResource)){
          if(pageContext. getHttpServletResponse().isCommitted()) return;
         
          OutputStream os=null;
          try {
                ci.writeTo(os=getOutputStream(),ReqRspUtil.getCharacterEncoding(pageContext,rsp));
            //IOUtil.copy(is=cacheResource.getInputStream(),os=getOutputStream(),false,false);
            }
            finally {
                IOUtil.flushEL(os);
                IOUtil.closeEL(os);
                ((PageContextImpl)pageContext).getRootOut().setClosed(true);
            }
          throw new Abort(Abort.SCOPE_REQUEST);
        }
       
        // call page again and
        //MetaData.getInstance(getDirectory()).add(ci.getName(), ci.getRaw());
       
        PageContextImpl pci = (PageContextImpl)pageContext;
        pci.getRootOut().doCache(ci);
         
    }

  /*private boolean isOK(Resource cacheResource) {
    return cacheResource.exists() && (cacheResource.lastModified()+timespan.getMillis()>=System.currentTimeMillis());
  }*/

  private int doContentCache() throws IOException {

        // file
        cacheItem = generateCacheResource(key,true);
        // use cache
        if(cacheItem.isValid(timespan)){
          pageContext.write(cacheItem.getValue());
          doCaching=false;
            return SKIP_BODY;
        }
      doCaching=true;
      return EVAL_BODY_BUFFERED;
  }

  private void doGet() throws PageException, IOException {
    required("cache", "id", id);
    required("cache", "name", name);
    String id=Caster.toString(this.id);
    if(metadata==null){
      pageContext.setVariable(name,CacheGet.call(pageContext, id,throwOnError,cachename))
    }
    else {
      railo.commons.io.cache.Cache cache =
        Util.getCache(pageContext,cachename,ConfigImpl.CACHE_DEFAULT_OBJECT);
      CacheEntry entry = throwOnError?cache.getCacheEntry(Util.key(id)):cache.getCacheEntry(Util.key(id),null);
      if(entry!=null){
        pageContext.setVariable(name,entry.getValue());
        pageContext.setVariable(metadata,entry.getCustomInfo());
      }
      else {
        pageContext.setVariable(metadata,new StructImpl());
      }
    }
   
   
   
   
   
   
   
   
  }
  private void doPut() throws PageException {
    required("cache", "id", id);
    required("cache", "value", value);
    TimeSpan ts = timespan;
    TimeSpan it = idletime;
    if(ts==TIMESPAN_FAR_AWAY)ts=TIMESPAN_0;
    if(it==TIMESPAN_FAR_AWAY)it=TIMESPAN_0;
    CachePut.call(pageContext, Caster.toString(id),value,ts,it,cachename);
  }
 

 

  private void doFlush() throws IOException, MalformedPatternException, PageException {
    if(id!=null){
      required("cache", "id", id);
      CacheRemove.call(pageContext, id,throwOnError,cachename);
    }
    else if(StringUtil.isEmpty(expireurl)) {
      CacheItem.flushAll(pageContext,directory,cachename);
    }
    else {
      CacheItem.flush(pageContext,directory,cachename,expireurl);
     
      //ResourceUtil.removeChildrenEL(getDirectory(),(ResourceNameFilter)new ExpireURLFilter(expireurl));
    }
    }


    private CacheItem generateCacheResource(String key, boolean useId) throws IOException {
      return CacheItem.getInstance(pageContext,_id,key,useId,directory,cachename,timespan);
  }

 

  private void writeCacheResource(CacheItem cacheItem, String result) throws IOException {
    cacheItem.store(result);
    //IOUtil.write(cacheItem.getResource(), result,"UTF-8", false);
    //MetaData.getInstance(cacheItem.getDirectory()).add(cacheItem.getName(), cacheItem.getRaw());
  }
 

    private DateTime getExpiresDate() {
    return new DateTimeImpl(pageContext,getExpiresTime(),false);
  }

  private long getExpiresTime() {
    return now.getTime()+(timespan.getMillis());
  }
 
  private OutputStream getOutputStream() throws PageException, IOException {
        try {
          return ((PageContextImpl)pageContext).getResponseStream();
        }
        catch(IllegalStateException ise) {
            throw new TemplateException("content is already send to user, flush");
        }
    }
 
 
  /**
     * sets if tag has a body or not
     * @param hasBody
     */
    public void hasBody(boolean hasBody) {
       this.hasBody=hasBody;
    }

  /**
   * @param id the id to set
   */
  public void set_id(String _id) {
    this._id = _id;
  }
 
  public void setId(Object id) {
    this.id = id;
  }
 
  public void setName(String name) {
    this.name = name;
  }
  public void setCachename(String cachename) {
    this.cachename = cachename;
  }
 
  /**
   * @param throwOnError the throwOnError to set
   */
  public void setThrowonerror(boolean throwOnError) {
    this.throwOnError = throwOnError;
  }
 
  public void setValue(Object value) {
    this.value = value;
  }
 
  /**
   * @param idletime the idletime to set
   */
  public void setIdletime(TimeSpan idletime) {
    this.idletime = idletime;
  }

  /**
   * @param metadata the metadata to set
   */
  public void setMetadata(String metadata) {
    this.metadata = metadata;
  }
}
 
TOP

Related Classes of railo.runtime.tag.Cache

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.