Package railo.runtime.listener

Source Code of railo.runtime.listener.ModernAppListener

package railo.runtime.listener;

import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.Cookie;

import railo.commons.io.DevNullOutputStream;
import railo.commons.io.res.Resource;
import railo.commons.io.res.util.ResourceUtil;
import railo.commons.lang.StringUtil;
import railo.commons.lang.mimetype.MimeType;
import railo.commons.lang.types.RefBoolean;
import railo.commons.lang.types.RefBooleanImpl;
import railo.runtime.CFMLFactory;
import railo.runtime.Component;
import railo.runtime.ComponentPage;
import railo.runtime.PageContext;
import railo.runtime.PageContextImpl;
import railo.runtime.PageSource;
import railo.runtime.component.ComponentLoader;
import railo.runtime.component.Member;
import railo.runtime.config.Constants;
import railo.runtime.engine.ThreadLocalPageContext;
import railo.runtime.exp.Abort;
import railo.runtime.exp.MissingIncludeException;
import railo.runtime.exp.PageException;
import railo.runtime.exp.PostContentAbort;
import railo.runtime.interpreter.JSONExpressionInterpreter;
import railo.runtime.net.http.HttpServletRequestDummy;
import railo.runtime.net.http.HttpServletResponseDummy;
import railo.runtime.net.http.ReqRspUtil;
import railo.runtime.op.Caster;
import railo.runtime.op.Decision;
import railo.runtime.op.Duplicator;
import railo.runtime.orm.ORMUtil;
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.cfc.ComponentAccess;
import railo.runtime.type.util.ArrayUtil;
import railo.runtime.type.util.KeyConstants;
import railo.runtime.type.util.UDFUtil;

public class ModernAppListener extends AppListenerSupport {



 

  private static final Collection.Key ON_REQUEST_START = KeyImpl.intern("onRequestStart");
  private static final Collection.Key ON_CFCREQUEST = KeyImpl.intern("onCFCRequest");
  private static final Collection.Key ON_REQUEST = KeyImpl.intern("onRequest");
  private static final Collection.Key ON_REQUEST_END = KeyImpl.intern("onRequestEnd");
  private static final Collection.Key ON_ABORT = KeyImpl.intern("onAbort");
  private static final Collection.Key ON_APPLICATION_START = KeyImpl.intern("onApplicationStart");
  private static final Collection.Key ON_APPLICATION_END = KeyImpl.intern("onApplicationEnd");
  private static final Collection.Key ON_SESSION_START = KeyImpl.intern("onSessionStart");
  private static final Collection.Key ON_SESSION_END = KeyImpl.intern("onSessionEnd");
  private static final Collection.Key ON_DEBUG = KeyImpl.intern("onDebug");
  private static final Collection.Key ON_ERROR = KeyImpl.intern("onError");
  private static final Collection.Key ON_MISSING_TEMPLATE = KeyImpl.intern("onMissingTemplate");
 
 
  //private ComponentImpl app;
  private Map<String,ComponentAccess> apps=new HashMap<String,ComponentAccess>();
  protected int mode=MODE_CURRENT2ROOT;
 
  @Override
  public void onRequest(PageContext pc, PageSource requestedPage, RequestListener rl) throws PageException {
    // on requestStart
    PageSource appPS=//pc.isCFCRequest()?null:
      AppListenerUtil.getApplicationPageSource(pc,requestedPage,Constants.APP_CFC,mode);
   
    _onRequest(pc, requestedPage, appPS,rl);
  }
 
  protected void _onRequest(PageContext pc, PageSource requestedPage,PageSource appPS, RequestListener rl) throws PageException {
    PageContextImpl pci = (PageContextImpl)pc;
    if(appPS!=null) {
      String callPath=appPS.getComponentName();
     
     
      ComponentAccess app = ComponentLoader.loadComponent(pci,null,appPS, callPath, false,false);
     
      // init
      initApplicationContext(pci,app);
       
     
      apps.put(pc.getApplicationContext().getName(), app);

      if(!pci.initApplicationContext(this)) return;
     
      if(rl!=null) {
        requestedPage=rl.execute(pc, requestedPage);
        if(requestedPage==null) return;
      }
     
      String targetPage=requestedPage.getFullRealpath();
      RefBoolean goon=new RefBooleanImpl(true);
     
      // onRequestStart
      if(app.contains(pc,ON_REQUEST_START)) {
        try {
          Object rtn=call(app,pci, ON_REQUEST_START, new Object[]{targetPage},false);
          if(!Caster.toBooleanValue(rtn,true))
            return;
        }
        catch(PageException pe){
          pe=handlePageException(pci,app,pe,requestedPage,targetPage,goon);
          if(pe!=null) throw pe;
        }
      }
       
      // onRequest
      if(goon.toBooleanValue()) {
      boolean isCFC=ResourceUtil.getExtension(targetPage,"").equalsIgnoreCase(pc.getConfig().getCFCExtension());
      Object method;
      if(isCFC && app.contains(pc,ON_CFCREQUEST) && (method=pc.urlFormScope().get(KeyConstants._method,null))!=null) {
       
        Struct url = (Struct)Duplicator.duplicate(pc.urlFormScope(),true);

        url.removeEL(KeyConstants._fieldnames);
        url.removeEL(KeyConstants._method);
       
        Object args=url.get(KeyConstants._argumentCollection,null);
       
        // url returnFormat
        Object oReturnFormat=url.removeEL(KeyConstants._returnFormat);
        int urlReturnFormat=-1;
        if(oReturnFormat!=null) urlReturnFormat=UDFUtil.toReturnFormat(Caster.toString(oReturnFormat,null),-1);
       
        // request header accept
        List<MimeType> accept = ReqRspUtil.getAccept(pc);
        int headerReturnFormat = MimeType.toFormat(accept, -1,-1);

            Object queryFormat=url.removeEL(KeyConstants._queryFormat);
           
            if(args==null){
              args=pc.getHttpServletRequest().getAttribute("argumentCollection");
            }
           
            if(args instanceof String){
              args=new JSONExpressionInterpreter().interpret(pc, (String)args);
            }
           
            if(args!=null) {
              if(Decision.isCastableToStruct(args)){
                Struct sct = Caster.toStruct(args,false);
                //Key[] keys = url.keys();
                Iterator<Entry<Key, Object>> it = url.entryIterator();
                Entry<Key, Object> e;
                while(it.hasNext()){
                  e = it.next();
                  sct.setEL(e.getKey(),e.getValue());
                }
                args=sct;
              }
              else if(Decision.isCastableToArray(args)){
                args = Caster.toArray(args);
              }
              else {
                Array arr = new ArrayImpl();
                arr.appendEL(args);
                args=arr;
              }
            }
            else
              args=url;

            Object rtn = call(app,pci, ON_CFCREQUEST, new Object[]{requestedPage.getComponentName(),method,args},true);
           
            if(rtn!=null){
              if(pc.getHttpServletRequest().getHeader("AMF-Forward")!=null) {
                pc.variablesScope().setEL("AMF-Forward", rtn);
                //ThreadLocalWDDXResult.set(rtn);
              }
              else {
                try {
              ComponentPage.writeToResponseStream(pc,app,method.toString(),urlReturnFormat,headerReturnFormat,queryFormat,rtn);
            } catch (Exception e) {
              throw Caster.toPageException(e);
            }
              }
            }
       
       
      }
      //else if(!isCFC && app.contains(pc,ON_REQUEST)) {}
      else {
        // TODO impl die nicht so generisch ist
        try{

          if(!isCFC && app.contains(pc,ON_REQUEST))
            call(app,pci, ON_REQUEST, new Object[]{targetPage},false);
          else
            pci.doInclude(requestedPage);
        }
        catch(PageException pe){
          pe=handlePageException(pci,app,pe,requestedPage,targetPage,goon);
          if(pe!=null) throw pe;
        }
      }
      }
      // onRequestEnd
      if(goon.toBooleanValue() && app.contains(pc,ON_REQUEST_END)) {
        try {
          call(app,pci, ON_REQUEST_END, new Object[]{targetPage},false);
        }
        catch(PageException pe){
          pe=handlePageException(pci,app,pe,requestedPage,targetPage,goon);
          if(pe!=null) throw pe;
        }
      }
    }
    else {
      apps.put(pc.getApplicationContext().getName(), null);
      pc.doInclude(requestedPage);
    }
  }
 

  private PageException handlePageException(PageContextImpl pci, ComponentAccess app, PageException pe, PageSource requestedPage, String targetPage, RefBoolean goon) throws PageException {
    PageException _pe=pe;
    if(pe instanceof ModernAppListenerException) {
      _pe=((ModernAppListenerException) pe).getPageException();
    }
   
    if(!Abort.isSilentAbort(_pe)) {
      if(_pe instanceof MissingIncludeException){
        if(((MissingIncludeException) _pe).getPageSource().equals(requestedPage)){
         
          if(app.contains(pci,ON_MISSING_TEMPLATE)) {
            goon.setValue(false);
            if(!Caster.toBooleanValue(call(app,pci, ON_MISSING_TEMPLATE, new Object[]{targetPage},true),true))
              return pe;
          }
          else return pe;
        }
        else return pe;
      }
      else return pe;
    }
    else {
      goon.setValue(false);
      if(app.contains(pci,ON_ABORT)) {
        call(app,pci, ON_ABORT, new Object[]{targetPage},true);
      }
    }
    return null;
  }

  @Override
  public boolean onApplicationStart(PageContext pc) throws PageException {
    ComponentAccess app = apps.get(pc.getApplicationContext().getName());
    if(app!=null && app.contains(pc,ON_APPLICATION_START)) {
      Object rtn = call(app,pc, ON_APPLICATION_START, ArrayUtil.OBJECT_EMPTY,true);
      return Caster.toBooleanValue(rtn,true);
    }
    return true;
  }

  @Override
  public void onApplicationEnd(CFMLFactory factory, String applicationName) throws PageException {
    ComponentAccess app = apps.get(applicationName);
    if(app==null || !app.containsKey(ON_APPLICATION_END)) return;
   
    PageContextImpl pc=(PageContextImpl) ThreadLocalPageContext.get();
    boolean createPc=pc==null;
    try {
      if(createPc)pc =  createPageContext(factory,app,applicationName,null,ON_APPLICATION_END);
      call(app,pc, ON_APPLICATION_END, new Object[]{pc.applicationScope()},true);
    }
    finally {
      if(createPc && pc!=null){
        factory.releasePageContext(pc);
      }
    }
  }
 
  @Override
  public void onSessionStart(PageContext pc) throws PageException {
    ComponentAccess app = apps.get(pc.getApplicationContext().getName());
    if(hasOnSessionStart(pc,app)) {
      call(app,pc, ON_SESSION_START, ArrayUtil.OBJECT_EMPTY,true);
    }
  }

  @Override
  public void onSessionEnd(CFMLFactory factory, String applicationName, String cfid) throws PageException {
    ComponentAccess app = apps.get(applicationName);
    if(app==null || !app.containsKey(ON_SESSION_END)) return;
   
    PageContextImpl pc=null;
    try {
      pc = createPageContext(factory,app,applicationName,cfid,ON_SESSION_END);
      call(app,pc, ON_SESSION_END, new Object[]{pc.sessionScope(false),pc.applicationScope()},true);
    }
    finally {
      if(pc!=null){
        factory.releasePageContext(pc);
      }
    }
  }

  private PageContextImpl createPageContext(CFMLFactory factory, ComponentAccess app, String applicationName, String cfid,Collection.Key methodName) throws PageException {
    Resource root = factory.getConfig().getRootDirectory();
    String path = app.getPageSource().getFullRealpath();
   
    // Request
    HttpServletRequestDummy req = new HttpServletRequestDummy(root,"localhost",path,"",null,null,null,null,null);
    if(!StringUtil.isEmpty(cfid))req.setCookies(new Cookie[]{new Cookie("cfid",cfid),new Cookie("cftoken","0")});
   
    // Response 
    OutputStream os=DevNullOutputStream.DEV_NULL_OUTPUT_STREAM;
    try {
      Resource out = factory.getConfig().getConfigDir().getRealResource("output/"+methodName.getString()+".out");
      out.getParentResource().mkdirs();
      os = out.getOutputStream(false);
    }
    catch (IOException e) {
      e.printStackTrace();
      // TODO was passiert hier
    }
    HttpServletResponseDummy rsp = new HttpServletResponseDummy(os);
   
    // PageContext
    PageContextImpl pc = (PageContextImpl) factory.getRailoPageContext(factory.getServlet(), req, rsp, null, false, -1, false);
    // ApplicationContext
    ClassicApplicationContext ap = new ClassicApplicationContext(factory.getConfig(),applicationName,false,app==null?null:ResourceUtil.getResource(pc,app.getPageSource(),null));
    initApplicationContext(pc, app);
    ap.setName(applicationName);
    ap.setSetSessionManagement(true);
    //if(!ap.hasName())ap.setName("Controler")
    // Base
    pc.setBase(app.getPageSource());
   
    return pc;
  }

  @Override
  public void onDebug(PageContext pc) throws PageException {
    if(((PageContextImpl)pc).isGatewayContext() || !pc.getConfig().debug()) return;
    ComponentAccess app = apps.get(pc.getApplicationContext().getName());
    if(app!=null && app.contains(pc,ON_DEBUG)) {
      call(app,pc, ON_DEBUG, new Object[]{pc.getDebugger().getDebuggingData(pc)},true);
      return;
    }
    try {
      pc.getDebugger().writeOut(pc);
    }
    catch (IOException e) {
      throw Caster.toPageException(e);
    }
  }

  @Override
  public void onError(PageContext pc, PageException pe) {
    ComponentAccess app =  apps.get(pc.getApplicationContext().getName());
    if(app!=null && app.containsKey(ON_ERROR) && !Abort.isSilentAbort(pe)) {
      try {
        String eventName="";
        if(pe instanceof ModernAppListenerException) eventName= ((ModernAppListenerException)pe).getEventName();
        if(eventName==null)eventName="";
       
        call(app,pc, ON_ERROR, new Object[]{pe.getCatchBlock(pc),eventName},true);
        return;
      }
      catch(PageException _pe) {
        pe=_pe;
      }
    }
    pc.handlePageException(pe);
  }


  private Object call(Component app, PageContext pc, Collection.Key eventName, Object[] args, boolean catchAbort) throws PageException {
    try {
      return app.call(pc, eventName, args);
    }
    catch (PageException pe) {
      if(Abort.isSilentAbort(pe)) {
        if(catchAbort)
          return ( pe instanceof PostContentAbort) ? Boolean.TRUE : Boolean.FALSE;

        throw pe;
      }
      throw new ModernAppListenerException(pe,eventName.getString());
    }
  }

  private void initApplicationContext(PageContextImpl pc, ComponentAccess app) throws PageException {
   
    // use existing app context
    RefBoolean throwsErrorWhileInit=new RefBooleanImpl(false);
    ModernApplicationContext appContext = new ModernApplicationContext(pc,app,throwsErrorWhileInit);

   
    pc.setApplicationContext(appContext);
    if(appContext.isORMEnabled()) {
      boolean hasError=throwsErrorWhileInit.toBooleanValue();
      if(hasError)pc.addPageSource(app.getPageSource(), true);
      try{
        ORMUtil.resetEngine(pc,false);
      }
      finally {
        if(hasError)pc.removeLastPageSource(true);
      }
    }
  }


  private static Object get(ComponentAccess app, Key name,String defaultValue) {
    Member mem = app.getMember(Component.ACCESS_PRIVATE, name, true, false);
    if(mem==null) return defaultValue;
    return mem.getValue();
  }

  @Override
  public void setMode(int mode) {
    this.mode=mode;
  }

  @Override
  public int getMode() {
    return mode;
  }
 

  @Override
  public String getType() {
    return "modern";
  }
 
  @Override
  public boolean hasOnSessionStart(PageContext pc) {
    return hasOnSessionStart(pc, apps.get(pc.getApplicationContext().getName()));
  }
  private boolean hasOnSessionStart(PageContext pc,ComponentAccess app) {
    return app!=null && app.contains(pc,ON_SESSION_START);
  }
}
TOP

Related Classes of railo.runtime.listener.ModernAppListener

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.