package railo.runtime.net.amf; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.Map.Entry; import railo.commons.lang.CFTypes; import railo.commons.lang.StringUtil; import railo.runtime.Component; import railo.runtime.ComponentWrap; import railo.runtime.engine.ThreadLocalPageContext; import railo.runtime.exp.PageException; import railo.runtime.op.Caster; import railo.runtime.op.Duplicator; import railo.runtime.type.Array; import railo.runtime.type.Collection; import railo.runtime.type.KeyImpl; import railo.runtime.type.Query; import railo.runtime.type.UDF; import railo.runtime.type.cfc.ComponentAccess; import railo.runtime.type.util.ArrayUtil; import railo.runtime.type.wrap.ArrayAsList; import flex.messaging.io.amf.ASObject; /** * Cast a CFML object to AMF Objects and the other way */ public final class ModernAMFCaster extends ClassicAMFCaster { private boolean doProperties=true; private boolean doGetters=true; private boolean doRemoteValues=true; @Override public void init(Map arguments){ super.init(arguments); String strValues = Caster.toString(arguments.get("component-values"),null); if(!StringUtil.isEmpty(strValues)){ doProperties = railo.runtime.type.util.ListUtil.listFindNoCase(strValues, "properties")!=-1; doGetters=railo.runtime.type.util.ListUtil.listFindNoCase(strValues, "getters")!=-1; doRemoteValues=railo.runtime.type.util.ListUtil.listFindNoCase(strValues, "remote-values")!=-1; } } public Object toAMFObject(Object cf) throws PageException { if(cf instanceof List) return toAMFObject((List)cf); if(cf instanceof Array) return toAMFObject(ArrayAsList.toList((Array)cf)); if(cf instanceof Component) return toAMFObject((Component)cf); if(cf instanceof Query) return super.toAMFObject((Query)cf); if(cf instanceof Map) return super.toAMFObject((Map)cf); if(cf instanceof Object[]) return toAMFObject((Object[])cf); return cf; } protected ASObject toAMFObject(Component cfc) throws PageException { // add properties ASObject aso = doProperties?super.toAMFObject(cfc):new ASObject(); ComponentWrap cw=null; if(cfc instanceof ComponentAccess)cw=ComponentWrap.toComponentWrap(Component.ACCESS_REMOTE,cfc); Iterator it = cfc.entrySet().iterator(); Map.Entry entry; Object v; Collection.Key k; UDF udf; String name; while(it.hasNext()) { entry=(Entry) it.next(); k=KeyImpl.toKey(entry.getKey()); v=entry.getValue(); // add getters if(v instanceof UDF){ if(!doGetters) continue; udf=(UDF) v; name=udf.getFunctionName(); if(!StringUtil.startsWithIgnoreCase(name, "get"))continue; if(udf.getReturnType()==CFTypes.TYPE_VOID) continue; if(udf.getFunctionArguments().length>0) continue; try { v=cfc.call(ThreadLocalPageContext.get(), name, ArrayUtil.OBJECT_EMPTY); } catch (PageException e) { continue; } name=name.substring(3); aso.put(toString(name,forceCFCLower), toAMFObject(v)); } // add remote data members if(cw!=null && doRemoteValues){ v=cw.get(k,null); if(v!=null)aso.put(toString(k,forceCFCLower), toAMFObject(v)); } } return aso; } protected Object toAMFObject(List list) throws PageException { list = Duplicator.duplicateList(list, false); ListIterator it = list.listIterator(); while(it.hasNext()) { list.set(it.nextIndex(),toAMFObject(it.next())); } return list; } protected Object toAMFObject(Object[] src) throws PageException { ArrayList list=new ArrayList(); for(int i=0;i<src.length;i++){ list.add(toAMFObject(src[i])); } return list; } }