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 **/ 019 package lucee.runtime.type; 020 021import lucee.commons.lang.CFTypes; 022import lucee.commons.lang.StringUtil; 023import lucee.runtime.ComponentImpl; 024import lucee.runtime.PageContext; 025import lucee.runtime.component.Property; 026import lucee.runtime.exp.ExpressionException; 027import lucee.runtime.exp.PageException; 028import lucee.runtime.listener.ApplicationContextPro; 029import lucee.runtime.op.Caster; 030import lucee.runtime.op.Decision; 031import lucee.runtime.orm.ORMUtil; 032import lucee.runtime.type.Collection.Key; 033import lucee.runtime.type.util.CollectionUtil; 034import lucee.runtime.type.util.KeyConstants; 035import lucee.runtime.type.util.UDFUtil; 036 037public final class UDFSetterProperty extends UDFGSProperty { 038 039 private static final Collection.Key VALIDATE_PARAMS = KeyImpl.intern("validateParams"); 040 private final Property prop; 041 private final Key propName; 042 private String validate; 043 private Struct validateParams; 044 045 public UDFSetterProperty(ComponentImpl component,Property prop) throws PageException { 046 super(component,"set"+StringUtil.ucFirst(prop.getName()),new FunctionArgument[]{ 047 new FunctionArgumentImpl( 048 KeyImpl.init(prop.getName()), 049 prop.getType(), 050 CFTypes.toShortStrict(prop.getType(),CFTypes.TYPE_UNKNOW), 051 true) 052 },CFTypes.TYPE_ANY,"wddx"); 053 054 this.prop=prop; 055 this.propName=KeyImpl.getInstance(prop.getName()); 056 057 this.validate=Caster.toString(prop.getDynamicAttributes().get(KeyConstants._validate,null),null); 058 if(!StringUtil.isEmpty(validate,true)) { 059 validate=validate.trim().toLowerCase(); 060 Object o = prop.getDynamicAttributes().get(VALIDATE_PARAMS,null); 061 if(o!=null){ 062 if(Decision.isStruct(o))validateParams=Caster.toStruct(o); 063 else { 064 String str=Caster.toString(o); 065 if(!StringUtil.isEmpty(str,true)) { 066 validateParams=ORMUtil.convertToSimpleMap(str); 067 if(validateParams==null) 068 throw new ExpressionException("cannot parse string ["+str+"] as struct"); 069 } 070 } 071 } 072 } 073 } 074 075 @Override 076 public UDF duplicate() { 077 try { 078 return new UDFSetterProperty(component,prop); 079 } catch (PageException e) { 080 return null; 081 } 082 } 083 084 @Override 085 public Object call(PageContext pageContext, Object[] args,boolean doIncludePath) throws PageException { 086 if(args.length<1) 087 throw new ExpressionException("The parameter "+prop.getName()+" to function "+getFunctionName()+" is required but was not passed in."); 088 validate(validate,validateParams,args[0]); 089 component.getComponentScope().set(propName, cast(pageContext,this.arguments[0],args[0],1)); 090 091 092 // make sure it is recognized that set is called by hibernate (if ORM is enabled) 093 ApplicationContextPro appContext = (ApplicationContextPro) pageContext.getApplicationContext(); 094 if(appContext.isORMEnabled() && component.isPersistent())ORMUtil.getSession(pageContext); 095 096 return component; 097 } 098 099 @Override 100 public Object callWithNamedValues(PageContext pageContext, Struct values,boolean doIncludePath) throws PageException { 101 UDFUtil.argumentCollection(values,getFunctionArguments()); 102 Object value = values.get(propName,null); 103 104 if(value==null){ 105 Key[] keys = CollectionUtil.keys(values); 106 if(keys.length==1) { 107 value=values.get(keys[0]); 108 } 109 else throw new ExpressionException("The parameter "+prop.getName()+" to function "+getFunctionName()+" is required but was not passed in."); 110 } 111 component.getComponentScope().set(propName, cast(pageContext,arguments[0],value,1)); 112 113 // make sure it is recognized that set is called by hibernate (if ORM is enabled) 114 ApplicationContextPro appContext = (ApplicationContextPro) pageContext.getApplicationContext(); 115 if(appContext.isORMEnabled() && component.isPersistent())ORMUtil.getSession(pageContext); 116 117 return component; 118 } 119 120 @Override 121 public Object getDefaultValue(PageContext pc, int index) throws PageException { 122 return prop.getDefault(); 123 } 124 125 @Override 126 public Object getDefaultValue(PageContext pc, int index, Object defaultValue) throws PageException { 127 return prop.getDefault(); 128 } 129 130 @Override 131 public String getReturnTypeAsString() { 132 return "any"; 133 } 134 135 @Override 136 public Object implementation(PageContext pageContext) throws Throwable { 137 return null; 138 } 139 140}