001    /**
002     * Implements the CFML Function arrayavg
003     */
004    package railo.runtime.functions.struct;
005    
006    import java.util.Iterator;
007    import java.util.Map.Entry;
008    
009    import railo.commons.lang.CFTypes;
010    import railo.runtime.PageContext;
011    import railo.runtime.exp.ExpressionException;
012    import railo.runtime.exp.PageException;
013    import railo.runtime.ext.function.Function;
014    import railo.runtime.op.Caster;
015    import railo.runtime.type.Collection.Key;
016    import railo.runtime.type.FunctionArgument;
017    import railo.runtime.type.Struct;
018    import railo.runtime.type.StructImpl;
019    import railo.runtime.type.UDF;
020    
021    
022    public final class StructFilter implements Function {
023    
024            private static final long serialVersionUID = -91410716194244194L;
025    
026            public static Struct call(PageContext pc , Struct sct, UDF filter) throws PageException {
027                    
028    
029                    // check UDF return type
030                    int type = filter.getReturnType();
031                    if(type!=CFTypes.TYPE_BOOLEAN && type!=CFTypes.TYPE_ANY)
032                            throw new ExpressionException("invalid return type ["+filter.getReturnTypeAsString()+"] for UDF Filter, valid return types are [boolean,any]");
033                    
034                    // check UDF arguments
035                    FunctionArgument[] args = filter.getFunctionArguments();
036                    if(args.length>2)
037                            throw new ExpressionException("UDF filter has to many arguments ["+args.length+"], should have at maximum 2 arguments");
038                    
039                    
040                    Struct rtn=new StructImpl();
041                    //Key[] keys = sct.keys();
042                    Iterator<Entry<Key, Object>> it = sct.entryIterator();
043                    Object value;
044                    while(it.hasNext()){
045                            Entry<Key, Object> e = it.next();
046                            value=e.getValue();
047                            if(Caster.toBooleanValue(filter.call(pc, new Object[]{e.getKey().getString(),value}, true)))
048                                    rtn.set(e.getKey(), value);
049                    }
050                    return rtn;
051            }
052    }