001 package railo.runtime.type; 002 003 import railo.commons.lang.CFTypes; 004 import railo.commons.lang.StringUtil; 005 import railo.runtime.ComponentImpl; 006 import railo.runtime.PageContext; 007 import railo.runtime.component.Property; 008 import railo.runtime.exp.ExpressionException; 009 import railo.runtime.exp.PageException; 010 import railo.runtime.op.Caster; 011 import railo.runtime.op.Decision; 012 import railo.runtime.orm.hibernate.HBMCreator; 013 import railo.runtime.type.Collection.Key; 014 015 public final class UDFSetterProperty extends UDFGSProperty { 016 017 private static final Collection.Key VALIDATE = KeyImpl.intern("validate"); 018 private static final Collection.Key VALIDATE_PARAMS = KeyImpl.intern("validateParams"); 019 private final Property prop; 020 private final Key propName; 021 private String validate; 022 private Struct validateParams; 023 024 public UDFSetterProperty(ComponentImpl component,Property prop) throws PageException { 025 super(component,"set"+StringUtil.ucFirst(prop.getName()),new FunctionArgument[]{ 026 new FunctionArgumentImpl(prop.getName(),prop.getType(),true) 027 },CFTypes.TYPE_ANY,"wddx"); 028 029 030 this.prop=prop; 031 this.propName=KeyImpl.getInstance(prop.getName()); 032 033 this.validate=Caster.toString(prop.getDynamicAttributes().get(VALIDATE,null),null); 034 if(!StringUtil.isEmpty(validate,true)) { 035 validate=validate.trim().toLowerCase(); 036 Object o = prop.getDynamicAttributes().get(VALIDATE_PARAMS,null); 037 if(o!=null){ 038 if(Decision.isStruct(o))validateParams=Caster.toStruct(o); 039 else { 040 String str=Caster.toString(o); 041 if(!StringUtil.isEmpty(str,true)) { 042 validateParams=HBMCreator.convertToSimpleMap(str); 043 if(validateParams==null) 044 throw new ExpressionException("cannot parse string ["+str+"] as struct"); 045 } 046 } 047 } 048 } 049 } 050 051 /** 052 * @see railo.runtime.type.UDF#duplicate() 053 */ 054 public UDF duplicate(ComponentImpl c) { 055 try { 056 return new UDFSetterProperty(c,prop); 057 } catch (PageException e) { 058 return null; 059 } 060 } 061 062 063 064 public UDF duplicate() { 065 return duplicate(component); 066 } 067 /** 068 * @see railo.runtime.type.UDF#call(railo.runtime.PageContext, java.lang.Object[], boolean) 069 */ 070 public Object call(PageContext pageContext, Object[] args,boolean doIncludePath) throws PageException { 071 if(args.length<1) 072 throw new ExpressionException("The parameter "+prop.getName()+" to function "+getFunctionName()+" is required but was not passed in."); 073 validate(validate,validateParams,args[0]); 074 component.getComponentScope().set(propName, cast(this.arguments[0],args[0],1)); 075 return component; 076 } 077 078 /** 079 * @see railo.runtime.type.UDF#callWithNamedValues(railo.runtime.PageContext, railo.runtime.type.Struct, boolean) 080 */ 081 public Object callWithNamedValues(PageContext pageContext, Struct values,boolean doIncludePath) throws PageException { 082 UDFImpl.argumentCollection(values,getFunctionArguments()); 083 Object value = values.get(propName,null); 084 085 if(value==null){ 086 Key[] keys = values.keys(); 087 if(keys.length==1) { 088 value=values.get(keys[0]); 089 } 090 else throw new ExpressionException("The parameter "+prop.getName()+" to function "+getFunctionName()+" is required but was not passed in."); 091 } 092 component.getComponentScope().set(propName, cast(arguments[0],value,1)); 093 return component; 094 } 095 096 /** 097 * @see railo.runtime.type.UDF#getDefaultValue(railo.runtime.PageContext, int) 098 */ 099 public Object getDefaultValue(PageContext pc, int index) throws PageException { 100 return prop.getDefault(); 101 } 102 103 /** 104 * @see railo.runtime.type.UDF#getReturnTypeAsString() 105 */ 106 public String getReturnTypeAsString() { 107 return "any"; 108 } 109 110 /** 111 * @see railo.runtime.type.UDF#implementation(railo.runtime.PageContext) 112 */ 113 public Object implementation(PageContext pageContext) throws Throwable { 114 return null; 115 } 116 117 }