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.PropertyFactory;
017    
018    public final class UDFHasProperty extends UDFGSProperty {
019    
020            private final Property prop;
021            //private ComponentScope scope;
022            
023            private final Key propName;
024            
025            //private static final String NULL="sdsdsdfsfsfjkln fsdfsa";
026    
027            public UDFHasProperty(ComponentImpl component,Property prop)  {
028                    super(component,"has"+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                            FunctionArgument key = new FunctionArgumentImpl(KeyImpl.KEY,"string",CFTypes.TYPE_STRING,false);
038                            return new FunctionArgument[]{key};
039                    }
040                    FunctionArgument value = new FunctionArgumentImpl(KeyImpl.init(PropertyFactory.getSingularName(prop)),"any",CFTypes.TYPE_ANY,false);
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 UDFHasProperty(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) return has(pageContext);
066                    return has(pageContext, args[0]);
067            }
068    
069            /**
070             * @see railo.runtime.type.UDF#callWithNamedValues(railo.runtime.PageContext, railo.runtime.type.Struct, boolean)
071             */
072            public Object callWithNamedValues(PageContext pageContext, Struct values,boolean doIncludePath) throws PageException {
073                    UDFImpl.argumentCollection(values,getFunctionArguments());
074                    Key key = arguments[0].getName();
075                    Object value = values.get(key,null);
076                    if(value==null){
077                            Key[] keys = values.keys();
078                            if(keys.length>0) {
079                                    value=values.get(keys[0]);
080                            }
081                            else return has(pageContext);
082                    }
083                    
084                    return has(pageContext, value);
085            }
086            
087            private boolean has(PageContext pageContext) {
088                    Object propValue = component.getComponentScope().get(propName,null);
089                    
090                    // struct
091                    if(isStruct()) {
092                            if(propValue instanceof Map) {
093                                    return !((Map)propValue).isEmpty();
094                            }
095                            return false;
096                    }
097                    else {
098                            Object o;
099                            if(propValue instanceof Array) {
100                                    Array arr = ((Array)propValue);
101                                    return arr.size()>0;
102                            }
103                            else if(propValue instanceof java.util.List) {
104                                    
105                                    return ((java.util.List)propValue).size()>0;
106                            }
107                            return propValue instanceof Component;
108                    }
109            }
110            
111            private boolean has(PageContext pageContext, Object value) throws PageException {
112                    Object propValue = component.getComponentScope().get(propName,null);
113                    
114                    // struct
115                    if(isStruct()) {
116                            String strKey = Caster.toString(value);
117                            //if(strKey==NULL) throw new ;
118                            
119                            if(propValue instanceof Struct) {
120                                    return ((Struct)propValue).containsKey(KeyImpl.getInstance(strKey));
121                            }
122                            else if(propValue instanceof Map) {
123                                    return ((Map)propValue).containsKey(strKey);
124                            }
125                            return false;
126                    }
127                    else {
128                            Object o;
129                            
130                            if(propValue instanceof Array) {
131                                    Array arr = ((Array)propValue);
132                                    Key[] keys = arr.keys();
133                                    for(int i=0;i<keys.length;i++){
134                                            o=arr.get(keys[i],null);
135                                            if(ORMUtil.equals(value,o))return true;
136                                    }
137                            }
138                            else if(propValue instanceof java.util.List) {
139                                    Iterator it=((java.util.List)propValue).iterator();
140                                    while(it.hasNext()){
141                                            o = it.next();
142                                            if(ORMUtil.equals(value,o))return true;
143                                    }
144                            }
145                            return false;
146                    }
147            }
148    
149            /**
150             * @see railo.runtime.type.UDF#implementation(railo.runtime.PageContext)
151             */
152            public Object implementation(PageContext pageContext) throws Throwable {
153                    return null;
154            }
155            
156            /**
157             * @see railo.runtime.type.UDF#getDefaultValue(railo.runtime.PageContext, int)
158             */
159            public Object getDefaultValue(PageContext pc, int index) throws PageException {
160                    return prop.getDefault();
161            }
162    
163            /**
164             * @see railo.runtime.type.UDF#getReturnTypeAsString()
165             */
166            public String getReturnTypeAsString() {
167                    return "boolean";
168            }
169    }