001    package railo.runtime.type;
002    
003    import java.io.IOException;
004    import java.io.ObjectInput;
005    import java.io.ObjectOutput;
006    
007    import railo.runtime.ComponentImpl;
008    import railo.runtime.PageContext;
009    import railo.runtime.dump.DumpData;
010    import railo.runtime.dump.DumpProperties;
011    import railo.runtime.engine.ThreadLocalPageContext;
012    import railo.runtime.exp.PageException;
013    import railo.runtime.type.scope.Variables;
014    import railo.runtime.type.util.ComponentUtil;
015    import railo.runtime.type.util.KeyConstants;
016    
017    public class Closure extends UDFImpl {
018            
019            
020            private Variables variables;
021    
022    
023            public Closure(){
024                    super();
025            }
026    
027            public Closure(UDFProperties properties) {
028                    super(properties);
029                    PageContext pc = ThreadLocalPageContext.get();
030                    if(pc.undefinedScope().getCheckArguments())
031                            this.variables=new railo.runtime.type.scope.Closure(pc,pc.argumentsScope(),pc.localScope(),pc.variablesScope());
032                    else{
033                            this.variables=pc.variablesScope();
034                            variables.setBind(true);
035                    }
036            }
037            
038            public Closure(UDFProperties properties, Variables variables) {
039                    super(properties);
040                    this.variables=variables;
041                    
042            }
043    
044            @Override
045            public UDF duplicate(ComponentImpl c) {
046                    // TODO Auto-generated method stub
047                    return super.duplicate(c);
048            }
049    
050            @Override
051            public Object callWithNamedValues(PageContext pc, Struct values, boolean doIncludePath) throws PageException {
052                    Variables parent=pc.variablesScope();
053            try{
054                    pc.setVariablesScope(variables);
055                    return super.callWithNamedValues(pc, values, doIncludePath);
056                    }
057                    finally {
058                            pc.setVariablesScope(parent);
059                    }
060            }
061    
062            @Override
063            public Object call(PageContext pc, Object[] args, boolean doIncludePath) throws PageException {
064                    Variables parent=pc.variablesScope();
065            try{
066                    pc.setVariablesScope(variables);
067                            return super.call(pc, args, doIncludePath);
068                    }
069                    finally {
070                            pc.setVariablesScope(parent);
071                    }
072            }
073    
074            @Override
075            public DumpData toDumpData(PageContext pageContext, int maxlevel,DumpProperties dp) {
076                    return toDumpData(pageContext, maxlevel, dp,this,true);
077            }
078    
079            @Override
080            public Struct getMetaData(PageContext pc) throws PageException {
081                    Struct meta = ComponentUtil.getMetaData(pc, properties);
082                    meta.setEL(KeyConstants._closure, Boolean.TRUE);// MUST move this to class UDFProperties
083                    meta.setEL("ANONYMOUSCLOSURE", Boolean.TRUE);// MUST move this to class UDFProperties
084                    
085                    return meta;
086            }
087    
088            public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
089                    // access
090                    setAccess(in.readInt());
091                    
092                    // properties
093                    properties=(UDFPropertiesImpl) in.readObject();
094            }
095    
096    
097            public void writeExternal(ObjectOutput out) throws IOException {
098                    // access
099                    out.writeInt(getAccess());
100                    
101                    // properties
102                    out.writeObject(properties);
103            }
104    }