001 package railo.runtime.type; 002 003 import java.util.HashMap; 004 import java.util.Map; 005 006 import railo.commons.lang.CFTypes; 007 import railo.commons.lang.StringUtil; 008 import railo.runtime.ComponentImpl; 009 import railo.runtime.PageContext; 010 import railo.runtime.component.Property; 011 import railo.runtime.exp.ExpressionException; 012 import railo.runtime.exp.PageException; 013 import railo.runtime.type.Collection.Key; 014 import railo.runtime.type.util.CollectionUtil; 015 import railo.runtime.type.util.KeyConstants; 016 import railo.runtime.type.util.PropertyFactory; 017 018 public final class UDFAddProperty extends UDFGSProperty { 019 020 private final Property prop; 021 //private ComponentScope scope; 022 023 private final Key propName; 024 025 private static final Object NULL=new Object(); 026 027 public UDFAddProperty(ComponentImpl component,Property prop) { 028 super(component,"add"+StringUtil.ucFirst(PropertyFactory.getSingularName(prop)),getFunctionArgument(prop),CFTypes.TYPE_ANY,"wddx"); 029 this.prop=prop; 030 this.propName=KeyImpl.getInstance(prop.getName()); 031 } 032 033 private static FunctionArgument[] getFunctionArgument(Property prop) { 034 String t = PropertyFactory.getType(prop); 035 FunctionArgument value = new FunctionArgumentImpl(KeyImpl.init(PropertyFactory.getSingularName(prop)),"any",CFTypes.TYPE_ANY,true); 036 if("struct".equalsIgnoreCase(t)){ 037 FunctionArgument key = new FunctionArgumentImpl(KeyConstants._key,"string",CFTypes.TYPE_STRING,true); 038 return new FunctionArgument[]{key,value}; 039 } 040 return new FunctionArgument[]{value}; 041 } 042 043 @Override 044 public UDF duplicate(ComponentImpl c) { 045 return new UDFAddProperty(c,prop); 046 } 047 048 049 public UDF duplicate() { 050 return duplicate(component); 051 } 052 053 @Override 054 public Object call(PageContext pageContext, Object[] args,boolean doIncludePath) throws PageException { 055 // struct 056 if(this.arguments.length==2) { 057 if(args.length<2) 058 throw new ExpressionException("The function "+getFunctionName()+" need 2 arguments, only "+args.length+" argment"+(args.length==1?" is":"s are")+" passed in."); 059 return _call(pageContext, args[0], args[1]); 060 } 061 // array 062 else if(this.arguments.length==1) { 063 if(args.length<1) 064 throw new ExpressionException("The parameter "+this.arguments[0].getName()+" to function "+getFunctionName()+" is required but was not passed in."); 065 return _call(pageContext, null, args[0]); 066 } 067 068 // never reached 069 return component; 070 071 } 072 073 @Override 074 public Object callWithNamedValues(PageContext pageContext, Struct values,boolean doIncludePath) throws PageException { 075 UDFImpl.argumentCollection(values,getFunctionArguments()); 076 077 078 // struct 079 if(this.arguments.length==2) { 080 Key keyName = arguments[0].getName(); 081 Key valueName = arguments[1].getName(); 082 Object key = values.get(keyName,null); 083 Object value = values.get(valueName,null); 084 if(key==null) 085 throw new ExpressionException("The parameter "+keyName+" to function "+getFunctionName()+" is required but was not passed in."); 086 if(value==null) 087 throw new ExpressionException("The parameter "+valueName+" to function "+getFunctionName()+" is required but was not passed in."); 088 089 return _call(pageContext, key, value); 090 } 091 // array 092 else if(this.arguments.length==1) { 093 Key valueName = arguments[0].getName(); 094 Object value = values.get(valueName,null); 095 if(value==null){ 096 Key[] keys = CollectionUtil.keys(values); 097 if(keys.length==1) { 098 value=values.get(keys[0]); 099 } 100 else throw new ExpressionException("The parameter "+valueName+" to function "+getFunctionName()+" is required but was not passed in."); 101 } 102 return _call(pageContext, null, value); 103 } 104 105 // never reached 106 return component; 107 } 108 109 110 private Object _call(PageContext pageContext, Object key, Object value) throws PageException { 111 112 113 Object propValue = component.getComponentScope().get(propName,null); 114 115 // struct 116 if(this.arguments.length==2) { 117 key=cast(arguments[0],key,1); 118 value=cast(arguments[1],value,2); 119 if(propValue==null){ 120 HashMap map=new HashMap(); 121 component.getComponentScope().setEL(propName,map); 122 propValue=map; 123 } 124 if(propValue instanceof Struct) { 125 ((Struct)propValue).set(KeyImpl.toKey(key), value); 126 } 127 else if(propValue instanceof Map) { 128 ((Map)propValue).put(key, value); 129 } 130 } 131 else { 132 value=cast(arguments[0],value,1); 133 if(propValue==null){ 134 /* jira2049 135 PageContext pc = ThreadLocalPageContext.get(); 136 ORMSession sess = ORMUtil.getSession(pc); 137 SessionImpl s=(SessionImpl) sess.getRawSession(); 138 propValue=new PersistentList(s); 139 component.getComponentScope().setEL(propName,propValue);*/ 140 Array arr=new ArrayImpl(); 141 component.getComponentScope().setEL(propName,arr); 142 propValue=arr; 143 } 144 if(propValue instanceof Array) { 145 ((Array)propValue).appendEL(value); 146 } 147 else if(propValue instanceof java.util.List) { 148 ((java.util.List)propValue).add(value); 149 } 150 } 151 return component; 152 } 153 154 @Override 155 public Object implementation(PageContext pageContext) throws Throwable { 156 return null; 157 } 158 159 @Override 160 public Object getDefaultValue(PageContext pc, int index) throws PageException { 161 return prop.getDefault(); 162 } 163 164 @Override 165 public Object getDefaultValue(PageContext pc, int index, Object defaultValue) throws PageException { 166 return prop.getDefault(); 167 } 168 169 @Override 170 public String getReturnTypeAsString() { 171 return "any"; 172 } 173 }