001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.runtime.net.amf; 020 021import java.util.ArrayList; 022import java.util.Iterator; 023import java.util.List; 024import java.util.ListIterator; 025import java.util.Map; 026import java.util.Map.Entry; 027 028import lucee.commons.lang.CFTypes; 029import lucee.commons.lang.StringUtil; 030import lucee.runtime.Component; 031import lucee.runtime.ComponentSpecificAccess; 032import lucee.runtime.engine.ThreadLocalPageContext; 033import lucee.runtime.exp.PageException; 034import lucee.runtime.op.Caster; 035import lucee.runtime.op.Duplicator; 036import lucee.runtime.type.Array; 037import lucee.runtime.type.Collection; 038import lucee.runtime.type.KeyImpl; 039import lucee.runtime.type.Query; 040import lucee.runtime.type.UDF; 041import lucee.runtime.type.util.ArrayUtil; 042import lucee.runtime.type.wrap.ArrayAsList; 043import flex.messaging.io.amf.ASObject; 044 045 046/** 047 * Cast a CFML object to AMF Objects and the other way 048 */ 049public final class ModernAMFCaster extends ClassicAMFCaster { 050 051 private boolean doProperties=true; 052 private boolean doGetters=true; 053 private boolean doRemoteValues=true; 054 055 @Override 056 public void init(Map arguments){ 057 super.init(arguments); 058 059 String strValues = Caster.toString(arguments.get("component-values"),null); 060 if(!StringUtil.isEmpty(strValues)){ 061 doProperties = lucee.runtime.type.util.ListUtil.listFindNoCase(strValues, "properties", ",")!=-1; 062 doGetters=lucee.runtime.type.util.ListUtil.listFindNoCase(strValues, "getters", ",")!=-1; 063 doRemoteValues=lucee.runtime.type.util.ListUtil.listFindNoCase(strValues, "remote-values", ",")!=-1; 064 } 065 } 066 067 public Object toAMFObject(Object cf) throws PageException { 068 if(cf instanceof List) return toAMFObject((List)cf); 069 if(cf instanceof Array) return toAMFObject(ArrayAsList.toList((Array)cf)); 070 if(cf instanceof Component) return toAMFObject((Component)cf); 071 if(cf instanceof Query) return super.toAMFObject((Query)cf); 072 if(cf instanceof Map) return super.toAMFObject((Map)cf); 073 if(cf instanceof Object[]) return toAMFObject((Object[])cf); 074 075 return cf; 076 } 077 078 079 protected ASObject toAMFObject(Component cfc) throws PageException { 080 // add properties 081 ASObject aso = doProperties?super.toAMFObject(cfc):new ASObject(); 082 ComponentSpecificAccess cw=ComponentSpecificAccess.toComponentSpecificAccess(Component.ACCESS_REMOTE,cfc); 083 084 Iterator it = cfc.entrySet().iterator(); 085 Map.Entry entry; 086 Object v; 087 Collection.Key k; 088 UDF udf; 089 String name; 090 while(it.hasNext()) { 091 entry=(Entry) it.next(); 092 k=KeyImpl.toKey(entry.getKey()); 093 v=entry.getValue(); 094 095 // add getters 096 if(v instanceof UDF){ 097 if(!doGetters) continue; 098 udf=(UDF) v; 099 name=udf.getFunctionName(); 100 if(!StringUtil.startsWithIgnoreCase(name, "get"))continue; 101 if(udf.getReturnType()==CFTypes.TYPE_VOID) continue; 102 if(udf.getFunctionArguments().length>0) continue; 103 104 try { 105 v=cfc.call(ThreadLocalPageContext.get(), name, ArrayUtil.OBJECT_EMPTY); 106 } catch (PageException e) { 107 continue; 108 } 109 name=name.substring(3); 110 111 aso.put(toString(name,forceCFCLower), toAMFObject(v)); 112 } 113 114 // add remote data members 115 if(cw!=null && doRemoteValues){ 116 v=cw.get(k,null); 117 if(v!=null)aso.put(toString(k,forceCFCLower), toAMFObject(v)); 118 } 119 } 120 return aso; 121 } 122 123 protected Object toAMFObject(List list) throws PageException { 124 list = Duplicator.duplicateList(list, false); 125 ListIterator it = list.listIterator(); 126 while(it.hasNext()) { 127 list.set(it.nextIndex(),toAMFObject(it.next())); 128 } 129 return list; 130 } 131 132 protected Object toAMFObject(Object[] src) throws PageException { 133 ArrayList list=new ArrayList(); 134 for(int i=0;i<src.length;i++){ 135 list.add(toAMFObject(src[i])); 136 } 137 return list; 138 } 139}