001    /**
002     * Implements the Cold Fusion Function structfindvalue
003     */
004    package railo.runtime.functions.struct;
005    
006    import railo.runtime.PageContext;
007    import railo.runtime.exp.FunctionException;
008    import railo.runtime.exp.PageException;
009    import railo.runtime.ext.function.Function;
010    import railo.runtime.op.Caster;
011    import railo.runtime.type.Array;
012    import railo.runtime.type.ArrayImpl;
013    import railo.runtime.type.Collection;
014    import railo.runtime.type.Collection.Key;
015    import railo.runtime.type.Struct;
016    import railo.runtime.type.StructImpl;
017    
018    public final class StructFindValue implements Function {
019            public static Array call(PageContext pc , railo.runtime.type.Struct struct, String value) throws PageException {
020                    return call(pc,struct,value,"one");
021            }
022            public static Array call(PageContext pc , Struct struct, String value, String scope) throws PageException {
023                    // Scope
024                boolean all=false;
025                if(scope.equalsIgnoreCase("one")) all=false;
026                else if(scope.equalsIgnoreCase("all")) all=true;
027                else throw new FunctionException(pc,"structFindValue",3,"scope","invalid scope definition ["+scope+"], valid scopes are [one, all]");
028                
029                Array array=new ArrayImpl();
030                getValues(pc,array,struct,value,all,"");
031                return array;
032            }
033        /**
034         * @param coll
035         * @param value
036         * @param all
037         * @param buffer
038         * @return
039         * @throws PageException
040         */
041        private static boolean getValues(PageContext pc,Array array,Collection coll, String value, boolean all, String path) throws PageException {
042            Key[] keys = coll.keys();
043            //print.ln("->"+List.arrayToList(keys,","));
044            boolean abort=false;
045            
046            
047            Key key;
048            loop:for(int i=0;i<keys.length;i++) {
049                if(abort)break loop;
050                key=keys[i];
051                Object o=coll.get(key);
052                
053                // Collection (this function search first for sub)
054                if(o instanceof Collection) {
055                    abort=getValues(pc,array,((Collection)o), value, all, StructFindKey.createKey(coll, path, key));
056                    
057                }
058                // matching value
059                if(!abort && !StructFindKey.isArray(coll)){
060                String target=Caster.toString(o,null);
061                if((target!=null && target.equalsIgnoreCase(value)) /*|| (o instanceof Array && checkSub(array,((Array)o),value,all,path,abort))*/) {
062                    Struct sct=new StructImpl();
063                            sct.setEL("key",key.getString());
064                                    sct.setEL("path",StructFindKey.createKey(coll, path, key));
065                                    sct.setEL("owner",coll);
066                    array.append(sct);
067                    if(!all)abort=true;
068                }
069            }
070            }
071            
072            return abort;
073        }
074    }