package railo.runtime.type;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import railo.runtime.ComponentImpl;
import railo.runtime.PageContext;
import railo.runtime.dump.DumpData;
import railo.runtime.dump.DumpProperties;
import railo.runtime.engine.ThreadLocalPageContext;
import railo.runtime.exp.PageException;
import railo.runtime.type.scope.ClosureScope;
import railo.runtime.type.scope.Variables;
import railo.runtime.type.util.ComponentUtil;
import railo.runtime.type.util.KeyConstants;
import railo.runtime.type.util.UDFUtil;
public class Closure extends UDFImpl {
private static final long serialVersionUID = -7200106903813254844L; // do not change
private Variables variables;
public Closure(){
super();
}
public Closure(UDFProperties properties) {
super(properties);
PageContext pc = ThreadLocalPageContext.get();
if(pc.undefinedScope().getCheckArguments())
this.variables=new ClosureScope(pc,pc.argumentsScope(),pc.localScope(),pc.variablesScope());
else{
this.variables=pc.variablesScope();
variables.setBind(true);
}
}
public Closure(UDFProperties properties, Variables variables) {
super(properties);
this.variables=variables;
}
@Override
public UDF duplicate(ComponentImpl c) {
Closure clo = new Closure(properties,variables);// TODO duplicate variables as well?
clo.ownerComponent=c;
clo.setAccess(getAccess());
return clo;
}
@Override
public Object callWithNamedValues(PageContext pc,Collection.Key calledName, Struct values, boolean doIncludePath) throws PageException {
Variables parent=pc.variablesScope();
try{
pc.setVariablesScope(variables);
return super.callWithNamedValues(pc, calledName,values, doIncludePath);
}
finally {
pc.setVariablesScope(parent);
}
}
@Override
public Object callWithNamedValues(PageContext pc, Struct values, boolean doIncludePath) throws PageException {
Variables parent=pc.variablesScope();
try{
pc.setVariablesScope(variables);
return super.callWithNamedValues(pc, values, doIncludePath);
}
finally {
pc.setVariablesScope(parent);
}
}
@Override
public Object call(PageContext pc,Collection.Key calledName, Object[] args, boolean doIncludePath) throws PageException {
Variables parent=pc.variablesScope();
try{
pc.setVariablesScope(variables);
return super.call(pc, calledName, args, doIncludePath);
}
finally {
pc.setVariablesScope(parent);
}
}
@Override
public Object call(PageContext pc, Object[] args, boolean doIncludePath) throws PageException {
Variables parent=pc.variablesScope();
try{
pc.setVariablesScope(variables);
return super.call(pc, args, doIncludePath);
}
finally {
pc.setVariablesScope(parent);
}
}
@Override
public DumpData toDumpData(PageContext pageContext, int maxlevel,DumpProperties dp) {
return UDFUtil.toDumpData(pageContext, maxlevel, dp,this,true);
}
@Override
public Struct getMetaData(PageContext pc) throws PageException {
Struct meta = ComponentUtil.getMetaData(pc, properties);
meta.setEL(KeyConstants._closure, Boolean.TRUE);// MUST move this to class UDFProperties
meta.setEL("ANONYMOUSCLOSURE", Boolean.TRUE);// MUST move this to class UDFProperties
return meta;
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
// access
setAccess(in.readInt());
// properties
properties=(UDFPropertiesImpl) in.readObject();
}
public void writeExternal(ObjectOutput out) throws IOException {
// access
out.writeInt(getAccess());
// properties
out.writeObject(properties);
}
}