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