001 package railo.runtime.type; 002 003 import java.util.Iterator; 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.op.Caster; 014 import railo.runtime.orm.ORMUtil; 015 import railo.runtime.type.Collection.Key; 016 import railo.runtime.type.util.PropertyFactory; 017 018 public final class UDFRemoveProperty 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 UDFRemoveProperty(ComponentImpl component,Property prop) { 028 super(component,"remove"+StringUtil.ucFirst(PropertyFactory.getSingularName(prop)),getFunctionArgument(prop),CFTypes.TYPE_BOOLEAN,"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 036 if("struct".equalsIgnoreCase(t)){ 037 FunctionArgumentImpl key = new FunctionArgumentImpl(KeyImpl.KEY,"string",CFTypes.TYPE_STRING,true); 038 return new FunctionArgument[]{key}; 039 } 040 FunctionArgumentImpl value = new FunctionArgumentImpl(KeyImpl.init(PropertyFactory.getSingularName(prop)),"any",CFTypes.TYPE_ANY,true); 041 return new FunctionArgument[]{value}; 042 } 043 044 private boolean isStruct() { 045 String t = PropertyFactory.getType(prop); 046 return "struct".equalsIgnoreCase(t); 047 } 048 049 /** 050 * @see railo.runtime.type.UDF#duplicate() 051 */ 052 public UDF duplicate(ComponentImpl c) { 053 return new UDFRemoveProperty(c,prop); 054 } 055 056 057 public UDF duplicate() { 058 return duplicate(component); 059 } 060 061 /** 062 * @see railo.runtime.type.UDF#call(railo.runtime.PageContext, java.lang.Object[], boolean) 063 */ 064 public Object call(PageContext pageContext, Object[] args,boolean doIncludePath) throws PageException { 065 if(args.length<1) 066 throw new ExpressionException("The parameter "+this.arguments[0].getName()+" to function "+getFunctionName()+" is required but was not passed in."); 067 068 return remove(pageContext, args[0]); 069 } 070 071 /** 072 * @see railo.runtime.type.UDF#callWithNamedValues(railo.runtime.PageContext, railo.runtime.type.Struct, boolean) 073 */ 074 public Object callWithNamedValues(PageContext pageContext, Struct values,boolean doIncludePath) throws PageException { 075 UDFImpl.argumentCollection(values,getFunctionArguments()); 076 Key key = arguments[0].getName(); 077 Object value = values.get(key,null); 078 if(value==null){ 079 Key[] keys = values.keys(); 080 if(keys.length==1) { 081 value=values.get(keys[0]); 082 } 083 else throw new ExpressionException("The parameter "+key+" to function "+getFunctionName()+" is required but was not passed in."); 084 } 085 086 return remove(pageContext, value); 087 } 088 089 090 private boolean remove(PageContext pageContext, Object value) throws PageException { 091 Object propValue = component.getComponentScope().get(propName,null); 092 value=cast(arguments[0],value,1); 093 094 // struct 095 if(isStruct()) { 096 String strKey = Caster.toString(value,null); 097 if(strKey==null) return false; 098 099 if(propValue instanceof Struct) { 100 return ((Struct)propValue).removeEL(KeyImpl.getInstance(strKey))!=null; 101 } 102 else if(propValue instanceof Map) { 103 return ((Map)propValue).remove(strKey)!=null; 104 } 105 return false; 106 } 107 else { 108 Object o; 109 boolean has=false; 110 if(propValue instanceof Array) { 111 Array arr = ((Array)propValue); 112 Key[] keys = arr.keys(); 113 for(int i=0;i<keys.length;i++){ 114 o=arr.get(keys[i],null); 115 if(ORMUtil.equals(value,o)){ 116 arr.removeEL(keys[i]); 117 has=true; 118 } 119 } 120 } 121 else if(propValue instanceof java.util.List) { 122 Iterator it=((java.util.List)propValue).iterator(); 123 while(it.hasNext()){ 124 o = it.next(); 125 if(ORMUtil.equals(value,o)){ 126 it.remove(); 127 has=true; 128 } 129 } 130 } 131 return has; 132 } 133 } 134 135 /** 136 * @see railo.runtime.type.UDF#implementation(railo.runtime.PageContext) 137 */ 138 public Object implementation(PageContext pageContext) throws Throwable { 139 return null; 140 } 141 142 /** 143 * @see railo.runtime.type.UDF#getDefaultValue(railo.runtime.PageContext, int) 144 */ 145 public Object getDefaultValue(PageContext pc, int index) throws PageException { 146 return prop.getDefault(); 147 } 148 149 /** 150 * @see railo.runtime.type.UDF#getReturnTypeAsString() 151 */ 152 public String getReturnTypeAsString() { 153 return "boolean"; 154 } 155 }