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.Component; 009 import railo.runtime.ComponentImpl; 010 import railo.runtime.PageContext; 011 import railo.runtime.component.Property; 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.CollectionUtil; 017 import railo.runtime.type.util.KeyConstants; 018 import railo.runtime.type.util.PropertyFactory; 019 020 public final class UDFHasProperty extends UDFGSProperty { 021 022 private final Property prop; 023 //private ComponentScope scope; 024 025 private final Key propName; 026 027 //private static final String NULL="sdsdsdfsfsfjkln fsdfsa"; 028 029 public UDFHasProperty(ComponentImpl component,Property prop) { 030 super(component,"has"+StringUtil.ucFirst(PropertyFactory.getSingularName(prop)),getFunctionArgument(prop),CFTypes.TYPE_BOOLEAN,"wddx"); 031 this.prop=prop; 032 this.propName=KeyImpl.getInstance(prop.getName()); 033 } 034 035 private static FunctionArgument[] getFunctionArgument(Property prop) { 036 String t = PropertyFactory.getType(prop); 037 038 if("struct".equalsIgnoreCase(t)){ 039 FunctionArgument key = new FunctionArgumentImpl(KeyConstants._key,"string",CFTypes.TYPE_STRING,false); 040 return new FunctionArgument[]{key}; 041 } 042 FunctionArgument value = new FunctionArgumentImpl(KeyImpl.init(PropertyFactory.getSingularName(prop)),"any",CFTypes.TYPE_ANY,false); 043 return new FunctionArgument[]{value}; 044 } 045 046 private boolean isStruct() { 047 String t = PropertyFactory.getType(prop); 048 return "struct".equalsIgnoreCase(t); 049 } 050 051 @Override 052 public UDF duplicate(ComponentImpl c) { 053 return new UDFHasProperty(c,prop); 054 } 055 056 057 public UDF duplicate() { 058 return duplicate(component); 059 } 060 061 @Override 062 public Object call(PageContext pageContext, Object[] args,boolean doIncludePath) throws PageException { 063 if(args.length<1) return has(pageContext); 064 return has(pageContext, args[0]); 065 } 066 067 @Override 068 public Object callWithNamedValues(PageContext pageContext, Struct values,boolean doIncludePath) throws PageException { 069 UDFImpl.argumentCollection(values,getFunctionArguments()); 070 Key key = arguments[0].getName(); 071 Object value = values.get(key,null); 072 if(value==null){ 073 Key[] keys = CollectionUtil.keys(values); 074 if(keys.length>0) { 075 value=values.get(keys[0]); 076 } 077 else return has(pageContext); 078 } 079 080 return has(pageContext, value); 081 } 082 083 private boolean has(PageContext pageContext) { 084 Object propValue = component.getComponentScope().get(propName,null); 085 086 // struct 087 if(isStruct()) { 088 if(propValue instanceof Map) { 089 return !((Map)propValue).isEmpty(); 090 } 091 return false; 092 } 093 094 //Object o; 095 if(propValue instanceof Array) { 096 Array arr = ((Array)propValue); 097 return arr.size()>0; 098 } 099 else if(propValue instanceof java.util.List) { 100 101 return ((java.util.List)propValue).size()>0; 102 } 103 return propValue instanceof Component; 104 105 } 106 107 private boolean has(PageContext pageContext, Object value) throws PageException { 108 Object propValue = component.getComponentScope().get(propName,null); 109 110 // struct 111 if(isStruct()) { 112 String strKey = Caster.toString(value); 113 //if(strKey==NULL) throw new ; 114 115 if(propValue instanceof Struct) { 116 return ((Struct)propValue).containsKey(KeyImpl.getInstance(strKey)); 117 } 118 else if(propValue instanceof Map) { 119 return ((Map)propValue).containsKey(strKey); 120 } 121 return false; 122 } 123 124 Object o; 125 126 if(propValue instanceof Array) { 127 Array arr = ((Array)propValue); 128 Iterator<Object> it = arr.valueIterator(); 129 while(it.hasNext()){ 130 if(ORMUtil.equals(value,it.next()))return true; 131 } 132 } 133 else if(propValue instanceof java.util.List) { 134 Iterator it=((java.util.List)propValue).iterator(); 135 while(it.hasNext()){ 136 o = it.next(); 137 if(ORMUtil.equals(value,o))return true; 138 } 139 } 140 return false; 141 142 } 143 144 @Override 145 public Object implementation(PageContext pageContext) throws Throwable { 146 return null; 147 } 148 149 @Override 150 public Object getDefaultValue(PageContext pc, int index) throws PageException { 151 return prop.getDefault(); 152 } 153 154 @Override 155 public Object getDefaultValue(PageContext pc, int index, Object defaultValue) throws PageException { 156 return prop.getDefault(); 157 } 158 159 @Override 160 public String getReturnTypeAsString() { 161 return "boolean"; 162 } 163 }