Package railo.runtime

Source Code of railo.runtime.CFMLFactoryImpl

package railo.runtime;

import java.net.URL;
import java.util.Iterator;
import java.util.Stack;

import javax.servlet.Servlet;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspEngineInfo;

import railo.commons.io.SystemUtil;
import railo.commons.io.log.Log;
import railo.commons.io.res.util.ResourceUtil;
import railo.commons.lang.SizeOf;
import railo.commons.lang.SystemOut;
import railo.runtime.config.ConfigWeb;
import railo.runtime.config.ConfigWebImpl;
import railo.runtime.engine.CFMLEngineImpl;
import railo.runtime.engine.ThreadLocalPageContext;
import railo.runtime.exp.Abort;
import railo.runtime.exp.PageException;
import railo.runtime.exp.PageExceptionImpl;
import railo.runtime.exp.RequestTimeoutException;
import railo.runtime.functions.string.Hash;
import railo.runtime.lock.LockManager;
import railo.runtime.op.Caster;
import railo.runtime.query.QueryCache;
import railo.runtime.type.Array;
import railo.runtime.type.ArrayImpl;
import railo.runtime.type.Collection;
import railo.runtime.type.Collection.Key;
import railo.runtime.type.KeyImpl;
import railo.runtime.type.Struct;
import railo.runtime.type.StructImpl;
import railo.runtime.type.dt.DateTimeImpl;
import railo.runtime.type.scope.ArgumentIntKey;
import railo.runtime.type.scope.LocalNotSupportedScope;
import railo.runtime.type.scope.ScopeContext;
import railo.runtime.type.util.ArrayUtil;
import railo.runtime.type.util.KeyConstants;
import railo.runtime.type.util.ListUtil;

/**
* implements a JSP Factory, this class produce JSP Compatible PageContext Object
* this object holds also the must interfaces to coldfusion specified functionlity
*/
public final class CFMLFactoryImpl extends CFMLFactory {
 
  private static JspEngineInfo info=new JspEngineInfoImpl("1.0");
  private ConfigWebImpl config;
  Stack<PageContext> pcs=new Stack<PageContext>();
    private Struct runningPcs=new StructImpl();
    int idCounter=1;
    private QueryCache queryCache;
    private ScopeContext scopeContext=new ScopeContext(this);
    private HttpServlet servlet;
  private URL url=null;
  private CFMLEngineImpl engine;

  /**
   * constructor of the JspFactory
   * @param config Railo specified Configuration
   * @param compiler CFML compiler
   * @param engine
   */
  public CFMLFactoryImpl(CFMLEngineImpl engine,QueryCache queryCache) {
    this.engine=engine;
    this.queryCache=queryCache;
  }
   
    /**
     * reset the PageContexes
     */
    public void resetPageContext() {
        SystemOut.printDate(config.getOutWriter(),"Reset "+pcs.size()+" Unused PageContexts");
        synchronized(pcs) {
            pcs.clear();
        }
       
        if(runningPcs!=null) {
          synchronized(runningPcs) {
          Iterator<Object> it = runningPcs.valueIterator();
          while(it.hasNext()){
            ((PageContextImpl)it.next()).reset();
          }
          }
        }
    }
   
  @Override
  public javax.servlet.jsp.PageContext getPageContext(
    Servlet servlet,
    ServletRequest req,
    ServletResponse rsp,
    String errorPageURL,
    boolean needsSession,
    int bufferSize,
    boolean autoflush) {
      return getPageContextImpl((HttpServlet)servlet,(HttpServletRequest)req,(HttpServletResponse)rsp,errorPageURL,needsSession,bufferSize,autoflush,true,false);
  }
 
  /**
   * similar to getPageContext Method but return the concrete implementation of the railo PageCOntext
   * and take the HTTP Version of the Servlet Objects
   * @param servlet
   * @param req
   * @param rsp
   * @param errorPageURL
   * @param needsSession
   * @param bufferSize
   * @param autoflush
   * @return return the page<context
   */
  public PageContext getRailoPageContext(
  HttpServlet servlet,
  HttpServletRequest req,
  HttpServletResponse rsp,
        String errorPageURL,
    boolean needsSession,
    int bufferSize,
    boolean autoflush)  {
        //runningCount++;
        return getPageContextImpl(servlet, req, rsp, errorPageURL, needsSession, bufferSize, autoflush,true,false);
  }
 
  public PageContextImpl getPageContextImpl(
      HttpServlet servlet,
      HttpServletRequest req,
      HttpServletResponse rsp,
            String errorPageURL,
        boolean needsSession,
        int bufferSize,
        boolean autoflush,boolean registerPageContext2Thread,boolean isChild)  {
            //runningCount++;
        PageContextImpl pc;
            synchronized (pcs) {
                if(pcs.isEmpty()) pc=new PageContextImpl(scopeContext,config,queryCache,idCounter++,servlet);
                else pc=((PageContextImpl)pcs.pop());
                runningPcs.setEL(ArgumentIntKey.init(pc.getId()),pc);
                this.servlet=servlet;
                if(registerPageContext2Thread)ThreadLocalPageContext.register(pc);
           
            }
            pc.initialize(servlet,req,rsp,errorPageURL,needsSession,bufferSize,autoflush,isChild);
            return pc;
      }

    @Override
  public void releasePageContext(javax.servlet.jsp.PageContext pc) {
    releaseRailoPageContext((PageContext)pc);
  }
 
  /**
   * Similar to the releasePageContext Method, but take railo PageContext as entry
   * @param pc
   */
  public void releaseRailoPageContext(PageContext pc) {
    if(pc.getId()<0)return;
        pc.release();
        ThreadLocalPageContext.release();
        //if(!pc.hasFamily()){
      synchronized (runningPcs) {
              runningPcs.removeEL(ArgumentIntKey.init(pc.getId()));
              if(pcs.size()<100)// not more than 100 PCs
                pcs.push(pc);
              //SystemOut.printDate(config.getOutWriter(),"Release: (id:"+pc.getId()+";running-requests:"+config.getThreadQueue().size()+";)");
          }
       /*}
        else {
           SystemOut.printDate(config.getOutWriter(),"Unlink: ("+pc.getId()+")");
        }*/
  }
   
    /**
   * check timeout of all running threads, downgrade also priority from all thread run longer than 10 seconds
   */
  public void checkTimeout() {
    if(!engine.allowRequestTimeout())return;
    synchronized (runningPcs) {
            //int len=runningPcs.size();
      Iterator it = runningPcs.keyIterator();
            PageContext pc;
            Collection.Key key;
            while(it.hasNext()) {
              key=KeyImpl.toKey(it.next(),null);
                //print.out("key:"+key);
                pc=(PageContext) runningPcs.get(key,null);
                if(pc==null) {
                  runningPcs.removeEL(key);
                  continue;
                }
               
                long timeout=pc.getRequestTimeout();
                if(pc.getStartTime()+timeout<System.currentTimeMillis()) {
                    terminate(pc);
                }
                // after 10 seconds downgrade priority of the thread
                else if(pc.getStartTime()+10000<System.currentTimeMillis() && pc.getThread().getPriority()!=Thread.MIN_PRIORITY) {
                    Log log = config.getRequestTimeoutLogger();
                    if(log!=null)log.warn("controller","downgrade priority of the a thread at "+getPath(pc));
                    try {
                      pc.getThread().setPriority(Thread.MIN_PRIORITY);
                    }
                    catch(Throwable t) {}
                }
            }
        }
  }
 
  public static void terminate(PageContext pc) {
    Log log = pc.getConfig().getRequestTimeoutLogger();
       
    String strLocks="";
    try{
      LockManager manager = pc.getConfig().getLockManager();
          String[] locks = manager.getOpenLockNames();
          if(!ArrayUtil.isEmpty(locks))
            strLocks=" open locks at this time ("+ListUtil.arrayToList(locks, ", ")+").";
          //LockManagerImpl.unlockAll(pc.getId());
    }
    catch(Throwable t){}
       
        if(log!=null)log.error("controller",
            "stop thread ("+pc.getId()+") because run into a timeout "+getPath(pc)+"."+strLocks);
        pc.getThread().stop(new RequestTimeoutException(pc,"request ("+getPath(pc)+":"+pc.getId()+") has run into a timeout ("+(pc.getRequestTimeout()/1000)+" seconds) and has been stopped."+strLocks));
       
  }

  private static String getPath(PageContext pc) {
    try {
      String base=ResourceUtil.getResource(pc, pc.getBasePageSource()).getAbsolutePath();
      String current=ResourceUtil.getResource(pc, pc.getCurrentPageSource()).getAbsolutePath();
      if(base.equals(current)) return "path: "+base;
      return "path: "+base+" ("+current+")";
    }
    catch(Throwable t) {
      return "";
    }
  }
 
  @Override
  public JspEngineInfo getEngineInfo() {
    return info;
  }


  /**
   * @return returns count of pagecontext in use
   */
  public int getUsedPageContextLength() {
    int length=0;
    try{
    Iterator it = runningPcs.values().iterator();
    while(it.hasNext()){
      PageContextImpl pc=(PageContextImpl) it.next();
      if(!pc.isGatewayContext()) length++;
    }
    }
    catch(Throwable t){
      return length;
    }
      return length;
  }
    /**
     * @return Returns the config.
     */
    public ConfigWeb getConfig() {
        return config;
    }
    public ConfigWebImpl getConfigWebImpl() {
        return config;
    }
    /**
     * @return Returns the scopeContext.
     */
    public ScopeContext getScopeContext() {
        return scopeContext;
    }

    /**
     * @return label of the factory
     */
    public Object getLabel() {
      return ((ConfigWebImpl)getConfig()).getLabel();
    }
    /**
     * @param label
     */
    public void setLabel(String label) {
        // deprecated
    }

  /**
   * @return the hostName
   */
  public URL getURL() {
    return url;
  }
   

  public void setURL(URL url) {
    this.url=url;
  }

  /**
   * @return the servlet
   */
  public HttpServlet getServlet() {
    return servlet;
  }

  public void setConfig(ConfigWebImpl config) {
    this.config=config;
  }

  public Struct getRunningPageContexts() {
    return runningPcs;
  }
 
  // exists because it is used in Morpheus
  public Struct getRunningPageContextes() {
    return getRunningPageContexts();
  }

  public long getPageContextsSize() {
    return SizeOf.size(pcs);
  }
 
  public Array getInfo() {
    Array info=new ArrayImpl();
   
    synchronized (runningPcs) {
            //int len=runningPcs.size();
      Iterator<Key> it = runningPcs.keyIterator();
            PageContextImpl pc;
            Struct data,sctThread,scopes;
        Collection.Key key;
            Thread thread;
        while(it.hasNext()) {
              data=new StructImpl();
              sctThread=new StructImpl();
              scopes=new StructImpl();
              data.setEL("thread", sctThread);
                data.setEL("scopes", scopes);
               
             
              key=KeyImpl.toKey(it.next(),null);
                //print.out("key:"+key);
                pc=(PageContextImpl) runningPcs.get(key,null);
                if(pc==null || pc.isGatewayContext()) continue;
                thread=pc.getThread();
                if(thread==Thread.currentThread()) continue;

               
                thread=pc.getThread();
                if(thread==Thread.currentThread()) continue;
               
              
               
                data.setEL("startTime", new DateTimeImpl(pc.getStartTime(),false));
                data.setEL("endTime", new DateTimeImpl(pc.getStartTime()+pc.getRequestTimeout(),false));
                data.setEL(KeyConstants._timeout,new Double(pc.getRequestTimeout()));

               
                // thread
                sctThread.setEL(KeyConstants._name,thread.getName());
                sctThread.setEL("priority",Caster.toDouble(thread.getPriority()));
                data.setEL("TagContext",PageExceptionImpl.getTagContext(pc.getConfig(),thread.getStackTrace() ));

                data.setEL("urlToken", pc.getURLToken());
                try {
          if(pc.getConfig().debug())data.setEL("debugger", pc.getDebugger().getDebuggingData(pc));
        } catch (PageException e2) {}

                try {
          data.setEL("id", Hash.call(pc, pc.getId()+":"+pc.getStartTime()));
        } catch (PageException e1) {}
                data.setEL("requestid", pc.getId());

                // Scopes
                scopes.setEL(KeyConstants._name, pc.getApplicationContext().getName());
                try {
          scopes.setEL(KeyConstants._application, pc.applicationScope());
        } catch (PageException e) {}

                try {
          scopes.setEL(KeyConstants._session, pc.sessionScope());
        } catch (PageException e) {}
               
                try {
          scopes.setEL(KeyConstants._client, pc.clientScope());
        } catch (PageException e) {}
                scopes.setEL(KeyConstants._cookie, pc.cookieScope());
                scopes.setEL(KeyConstants._variables, pc.variablesScope());
                if(!(pc.localScope() instanceof LocalNotSupportedScope)){
                  scopes.setEL(KeyConstants._local, pc.localScope());
                  scopes.setEL(KeyConstants._arguments, pc.argumentsScope());
                }
                scopes.setEL(KeyConstants._cgi, pc.cgiScope());
                scopes.setEL(KeyConstants._form, pc.formScope());
                scopes.setEL(KeyConstants._url, pc.urlScope());
                scopes.setEL(KeyConstants._request, pc.requestScope());
               
                info.appendEL(data);
            }
            return info;
        }
  }

  public void stopThread(String threadId, String stopType) {
    synchronized (runningPcs) {
            //int len=runningPcs.size();
      Iterator it = runningPcs.keyIterator();
            PageContext pc;
        while(it.hasNext()) {
             
              pc=(PageContext) runningPcs.get(KeyImpl.toKey(it.next(),null),null);
                if(pc==null) continue;
                try {
          String id = Hash.call(pc, pc.getId()+":"+pc.getStartTime());
          if(id.equals(threadId)){
            stopType=stopType.trim();
            Throwable t;
            if("abort".equalsIgnoreCase(stopType) || "cfabort".equalsIgnoreCase(stopType))
              t=new Abort(Abort.SCOPE_REQUEST);
            else
              t=new RequestTimeoutException(pc,"request has been forced to stop.");
           
                    pc.getThread().stop(t);
                    SystemUtil.sleep(10);
            break;
          }
        } catch (PageException e1) {}
               
            }
        }
  }

  @Override
  public QueryCache getDefaultQueryCache() {
    return queryCache;
  }
}
TOP

Related Classes of railo.runtime.CFMLFactoryImpl

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.