/** * * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see <http://www.gnu.org/licenses/>. * **/ /** * Implements the CFML Function structfindvalue */ package lucee.runtime.functions.struct; import java.util.Iterator; import java.util.Map.Entry; import lucee.runtime.PageContext; import lucee.runtime.exp.FunctionException; import lucee.runtime.exp.PageException; import lucee.runtime.ext.function.BIF; import lucee.runtime.op.Caster; import lucee.runtime.type.Array; import lucee.runtime.type.ArrayImpl; import lucee.runtime.type.Collection; import lucee.runtime.type.Collection.Key; import lucee.runtime.type.Struct; import lucee.runtime.type.StructImpl; import lucee.runtime.type.util.KeyConstants; public final class StructFindValue extends BIF { private static final long serialVersionUID = 1499023912262918840L; public static Array call(PageContext pc , lucee.runtime.type.Struct struct, String value) throws PageException { return call(pc,struct,value,"one"); } public static Array call(PageContext pc , Struct struct, String value, String scope) throws PageException { // Scope boolean all=false; if(scope.equalsIgnoreCase("one")) all=false; else if(scope.equalsIgnoreCase("all")) all=true; else throw new FunctionException(pc,"structFindValue",3,"scope","invalid scope definition ["+scope+"], valid scopes are [one, all]"); Array array=new ArrayImpl(); getValues(pc,array,struct,value,all,""); return array; } /** * @param coll * @param value * @param all * @param buffer * @return * @throws PageException */ private static boolean getValues(PageContext pc,Array array,Collection coll, String value, boolean all, String path) throws PageException { //Key[] keys = coll.keys(); boolean abort=false; Key key; Iterator<Entry<Key, Object>> it = coll.entryIterator(); Entry<Key, Object> e; loop:while(it.hasNext()) { e = it.next(); if(abort)break loop; key=e.getKey(); Object o=e.getValue(); // Collection (this function search first for sub) if(o instanceof Collection) { abort=getValues(pc,array,((Collection)o), value, all, StructFindKey.createKey(coll, path, key)); } // matching value if(!abort && !StructFindKey.isArray(coll)){ String target=Caster.toString(o,null); if((target!=null && target.equalsIgnoreCase(value)) /*|| (o instanceof Array && checkSub(array,((Array)o),value,all,path,abort))*/) { Struct sct=new StructImpl(); sct.setEL(KeyConstants._key,key.getString()); sct.setEL(KeyConstants._path,StructFindKey.createKey(coll, path, key)); sct.setEL(KeyConstants._owner,coll); array.append(sct); if(!all)abort=true; } } } return abort; } @Override public Object invoke(PageContext pc, Object[] args) throws PageException { if(args.length==3) return call(pc,Caster.toStruct(args[0]),Caster.toString(args[1]),Caster.toString(args[2])); return call(pc,Caster.toStruct(args[0]),Caster.toString(args[1])); } }