Package railo.runtime.functions.system

Source Code of railo.runtime.functions.system.CFFunction

package railo.runtime.functions.system;

import java.io.File;

import railo.runtime.Mapping;
import railo.runtime.Page;
import railo.runtime.PageContext;
import railo.runtime.PageSourceImpl;
import railo.runtime.config.ConfigWebImpl;
import railo.runtime.exp.ExpressionException;
import railo.runtime.exp.PageException;
import railo.runtime.op.Caster;
import railo.runtime.op.Duplicator;
import railo.runtime.type.Collection;
import railo.runtime.type.FunctionValue;
import railo.runtime.type.KeyImpl;
import railo.runtime.type.Struct;
import railo.runtime.type.StructImpl;
import railo.runtime.type.UDF;
import railo.runtime.type.UDFPlus;
import railo.runtime.type.scope.Variables;
import railo.runtime.type.scope.VariablesImpl;
import railo.runtime.type.util.ArrayUtil;
import railo.runtime.type.util.KeyConstants;

public class CFFunction {
 
 
  private static final Variables VAR = new VariablesImpl();
  //private static Map udfs=new ReferenceMap();
 
  public static Object call(PageContext pc , Object[] objArr) throws PageException {
    if(objArr.length<3)
      throw new ExpressionException("invalid call of a CFML Based built in function");
   
    // translate arguments
    String filename=Caster.toString((((FunctionValue) objArr[0]).getValue()));
    Collection.Key name=KeyImpl.toKey((((FunctionValue) objArr[1]).getValue()));
    boolean isweb=Caster.toBooleanValue((((FunctionValue) objArr[2]).getValue()));
   
   
    UDF udf=loadUDF(pc, filename, name, isweb);
    Struct meta = udf.getMetaData(pc);
    boolean caller=meta==null?false:Caster.toBooleanValue(meta.get(KeyConstants._caller,Boolean.FALSE),false);
   
    Struct namedArguments=null;
    Object[] arguments=null;
    if(objArr.length<=3)arguments=ArrayUtil.OBJECT_EMPTY;
    else if(objArr[3] instanceof FunctionValue){
      FunctionValue fv;
      namedArguments=new StructImpl();
      if(caller)namedArguments.setEL(KeyConstants._caller, Duplicator.duplicate(pc.undefinedScope(),false));
      for(int i=3;i<objArr.length;i++){
        fv=toFunctionValue(name,objArr[i]);
        namedArguments.set(fv.getName(), fv.getValue());
      }
    }
    else {
      int offset=(caller?2:3);
      arguments=new Object[objArr.length-offset];
      if(caller)arguments[0]=Duplicator.duplicate(pc.undefinedScope(),false);
      for(int i=3;i<objArr.length;i++){
        arguments[i-offset]=toObject(name,objArr[i]);
      }
    }
   
   
    // load UDF
   
   
    // execute UDF
    if(namedArguments==null){
      return ((UDFPlus)udf).call(pc,name, arguments, false);
    }
   
   
    return ((UDFPlus)udf).callWithNamedValues(pc,name, namedArguments, false);
  }

  public static synchronized UDF loadUDF(PageContext pc, String filename,Collection.Key name,boolean isweb) throws PageException {
    ConfigWebImpl config = (ConfigWebImpl) pc.getConfig();
    String key=isweb?name.getString()+config.getId():name.getString();
      UDF udf=config.getFromFunctionCache(key);
    if(udf!=null) return udf;
   
    Mapping mapping=isweb?config.getFunctionMapping():config.getServerFunctionMapping();
      PageSourceImpl ps = (PageSourceImpl) mapping.getPageSource(filename);
      Page p = ps.loadPage(pc)
   
     
      // execute page
      Variables old = pc.variablesScope();
      pc.setVariablesScope(VAR);
      boolean wasSilent = pc.setSilent();
      try {
      p.call(pc);
      Object o= pc.variablesScope().get(name,null);
      if(o instanceof UDF) {
        udf= (UDF) o;
        config.putToFunctionCache(key, udf);
        return udf;
      }
      throw new ExpressionException("there is no Function defined with name ["+name+"] in template ["+mapping.getStrPhysical()+File.separator+filename+"]");
    }
      catch (Throwable t) {
      throw Caster.toPageException(t);
    }
    finally{
      pc.setVariablesScope(old);
      if(!wasSilent)pc.unsetSilent();
    }
   
   
  }

  private static FunctionValue toFunctionValue(Collection.Key name,Object obj) throws ExpressionException {
    if(obj instanceof FunctionValue)
      return (FunctionValue) obj;
    throw new ExpressionException("invalid argument for function "+name+", you can not mix named and unnamed arguments");
  }

  private static Object toObject(Collection.Key name,Object obj) throws ExpressionException {
    if(obj instanceof FunctionValue)
      throw new ExpressionException("invalid argument for function "+name+", you can not mix named and unnamed arguments");
    return obj;
  }
}
TOP

Related Classes of railo.runtime.functions.system.CFFunction

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.