001 package railo.transformer.library.function; 002 003 import java.io.IOException; 004 import java.util.ArrayList; 005 import java.util.Iterator; 006 007 import railo.commons.lang.CFTypes; 008 import railo.commons.lang.ClassException; 009 import railo.commons.lang.ClassUtil; 010 import railo.commons.lang.Md5; 011 import railo.commons.lang.StringUtil; 012 import railo.runtime.exp.ExpressionException; 013 import railo.runtime.exp.PageRuntimeException; 014 import railo.runtime.exp.TemplateException; 015 import railo.runtime.functions.BIF; 016 import railo.runtime.functions.BIFProxy; 017 import railo.runtime.reflection.Reflector; 018 import railo.transformer.cfml.evaluator.FunctionEvaluator; 019 import railo.transformer.library.tag.TagLib; 020 021 022 023 /** 024 * Eine FunctionLibFunction repraesentiert eine einzelne Funktion innerhalb einer FLD. 025 */ 026 public final class FunctionLibFunction { 027 028 /** 029 * Dynamischer Argument Typ 030 */ 031 public static final int ARG_DYNAMIC = 0; 032 /** 033 * statischer Argument Typ 034 */ 035 public static final int ARG_FIX = 1; 036 037 038 private FunctionLib functionLib; 039 private String name; 040 private ArrayList<FunctionLibFunctionArg> argument=new ArrayList<FunctionLibFunctionArg>(); 041 042 private int argMin=0; 043 private int argMax=-1; 044 private int argType=ARG_FIX; 045 046 047 private String strReturnType; 048 049 private String cls=""; 050 private Class clazz; 051 private String description; 052 private boolean hasDefaultValues; 053 private FunctionEvaluator eval; 054 private String tteClass; 055 private short status=TagLib.STATUS_IMPLEMENTED; 056 private String memberName; 057 private short memberType=CFTypes.TYPE_UNKNOW; 058 private boolean memberChaining; 059 private BIF bif; 060 061 062 /** 063 * Geschuetzer Konstruktor ohne Argumente. 064 */ 065 public FunctionLibFunction() { 066 } 067 public FunctionLibFunction(FunctionLib functionLib) { 068 this.functionLib=functionLib; 069 } 070 071 /** 072 * Gibt den Namen der Funktion zurueck. 073 * @return name Name der Funktion. 074 */ 075 public String getName() { 076 return name; 077 } 078 079 /** 080 * Gibt alle Argumente einer Funktion als ArrayList zurueck. 081 * @return Argumente der Funktion. 082 */ 083 public ArrayList<FunctionLibFunctionArg> getArg() { 084 return argument; 085 } 086 087 /** 088 * Gibt zurueck wieviele Argumente eine Funktion minimal haben muss. 089 * @return Minimale Anzahl Argumente der Funktion. 090 */ 091 public int getArgMin() { 092 return argMin; 093 } 094 095 /** 096 * Gibt zurueck wieviele Argumente eine Funktion minimal haben muss. 097 * @return Maximale Anzahl Argumente der Funktion. 098 */ 099 public int getArgMax() { 100 return argMax; 101 } 102 103 /** 104 * @return the status (TagLib.,TagLib.STATUS_IMPLEMENTED,TagLib.STATUS_DEPRECATED,TagLib.STATUS_UNIMPLEMENTED) 105 */ 106 public short getStatus() { 107 return status; 108 } 109 110 111 /** 112 * @param status the status to set (TagLib.,TagLib.STATUS_IMPLEMENTED,TagLib.STATUS_DEPRECATED,TagLib.STATUS_UNIMPLEMENTED) 113 */ 114 public void setStatus(short status) { 115 this.status = status; 116 } 117 118 119 /** 120 * Gibt die argument art zurueck. 121 * @return argument art 122 */ 123 public int getArgType() { 124 return argType; 125 } 126 127 /** 128 * Gibt die argument art als String zurueck. 129 * @return argument art 130 */ 131 public String getArgTypeAsString() { 132 if(argType==ARG_DYNAMIC) return "dynamic"; 133 return "fixed"; 134 } 135 136 /** 137 * Gibt zurueck von welchem Typ der Rueckgabewert dieser Funktion sein muss (query, string, struct, number usw.). 138 * @return Typ des Rueckgabewert. 139 */ 140 public String getReturnTypeAsString() { 141 return strReturnType; 142 } 143 144 /** 145 * Gibt die Klassendefinition als Zeichenkette zurueck, welche diese Funktion implementiert. 146 * @return Klassendefinition als Zeichenkette. 147 */ 148 public String getCls() { 149 return cls; 150 } 151 152 /** 153 * Gibt die Klasse zurueck, welche diese Funktion implementiert. 154 * @return Klasse der Function. 155 */ 156 public Class getClazz() { 157 if(clazz==null) { 158 clazz=ClassUtil.loadClass(cls,(Class)null); 159 } 160 return clazz; 161 } 162 163 /** 164 * Gibt die Beschreibung der Funktion zurueck. 165 * @return String 166 */ 167 public String getDescription() { 168 return description; 169 } 170 171 /** 172 * Gibt die FunctionLib zurueck, zu der die Funktion gehoert. 173 * @return Zugehoerige FunctionLib. 174 */ 175 public FunctionLib getFunctionLib() { 176 return functionLib; 177 } 178 179 /** 180 * Setzt den Namen der Funktion. 181 * @param name Name der Funktion. 182 */ 183 public void setName(String name) { 184 this.name = name.toLowerCase(); 185 } 186 187 /** 188 * Fuegt der Funktion ein Argument hinzu. 189 * @param arg Argument zur Funktion. 190 */ 191 public void addArg(FunctionLibFunctionArg arg) { 192 arg.setFunction(this); 193 argument.add(arg); 194 if(arg.getDefaultValue()!=null) 195 hasDefaultValues=true; 196 } 197 198 /** 199 * Fuegt der Funktion ein Argument hinzu, alias fuer addArg. 200 * @param arg Argument zur Funktion. 201 */ 202 public void setArg(FunctionLibFunctionArg arg) { 203 addArg(arg); 204 } 205 206 207 /** 208 * Setzt wieviele Argumente eine Funktion minimal haben muss. 209 * @param argMin Minimale Anzahl Argumente der Funktion. 210 */ 211 public void setArgMin(int argMin) { 212 this.argMin = argMin; 213 } 214 215 /** 216 * Setzt wieviele Argumente eine Funktion minimal haben muss. 217 * @param argMax Maximale Anzahl Argumente der Funktion. 218 */ 219 public void setArgMax(int argMax) { 220 this.argMax = argMax; 221 } 222 223 /** 224 * Setzt den Rueckgabewert der Funktion (query,array,string usw.) 225 * @param value 226 */ 227 public void setReturn(String value) { 228 strReturnType=value; 229 } 230 231 /** 232 * Setzt die Klassendefinition als Zeichenkette, welche diese Funktion implementiert. 233 * @param value Klassendefinition als Zeichenkette. 234 */ 235 public void setCls(String value) { 236 cls+=value; 237 238 } 239 240 /** 241 * Setzt die Beschreibung der Funktion. 242 * @param description Beschreibung der Funktion. 243 */ 244 public void setDescription(String description) { 245 this.description = description; 246 } 247 248 /** 249 * Setzt die zugehoerige FunctionLib. 250 * @param functionLib Zugehoerige FunctionLib. 251 */ 252 public void setFunctionLib(FunctionLib functionLib) { 253 this.functionLib=functionLib; 254 } 255 256 /** 257 * sets the argument type of the function 258 * @param argType 259 */ 260 public void setArgType(int argType) { 261 this.argType=argType; 262 } 263 264 265 public String getHash() { 266 StringBuffer sb=new StringBuffer(); 267 sb.append(this.getArgMax()); 268 sb.append(this.getArgMin()); 269 sb.append(this.getArgType()); 270 sb.append(this.getArgTypeAsString()); 271 sb.append(this.getCls()); 272 sb.append(this.getName()); 273 sb.append(this.getReturnTypeAsString()); 274 275 Iterator it = this.getArg().iterator(); 276 FunctionLibFunctionArg arg; 277 while(it.hasNext()){ 278 arg=(FunctionLibFunctionArg) it.next(); 279 sb.append(arg.getHash()); 280 } 281 282 try { 283 return Md5.getDigestAsString(sb.toString()); 284 } catch (IOException e) { 285 return ""; 286 } 287 } 288 public boolean hasDefaultValues() { 289 return hasDefaultValues; 290 } 291 292 public boolean hasTteClass() { 293 return tteClass !=null && tteClass.length()>0; 294 } 295 296 public FunctionEvaluator getEvaluator() throws TemplateException { 297 if(!hasTteClass()) return null; 298 if(eval!=null) return eval; 299 try { 300 eval = (FunctionEvaluator) ClassUtil.loadInstance(tteClass); 301 } 302 catch (ClassException e) { 303 throw new TemplateException(e.getMessage()); 304 } 305 return eval; 306 } 307 public void setTteClass(String tteClass) { 308 this.tteClass=tteClass; 309 } 310 public void setMemberName(String memberName) { 311 if(StringUtil.isEmpty(memberName,true)) return; 312 this.memberName=memberName.trim(); 313 } 314 public String getMemberName() { 315 return memberName; 316 } 317 public void setMemberChaining(boolean memberChaining) { 318 this.memberChaining=memberChaining; 319 } 320 public boolean getMemberChaining() { 321 return memberChaining; 322 } 323 324 public short getMemberType() { 325 if(memberName!=null && memberType==CFTypes.TYPE_UNKNOW){ 326 ArrayList<FunctionLibFunctionArg> args = getArg(); 327 if(args.size()>=1){ 328 memberType=CFTypes.toShortStrict(args.get(0).getTypeAsString(),CFTypes.TYPE_UNKNOW); 329 } 330 } 331 return memberType; 332 } 333 public String getMemberTypeAsString() { 334 return CFTypes.toString(getMemberType(),"any"); 335 } 336 public BIF getBIF() { 337 if(bif!=null) return bif; 338 339 Class clazz=getClazz(); 340 if(clazz==null)throw new PageRuntimeException(new ExpressionException("class "+clazz+" not found")); 341 342 if(Reflector.isInstaneOf(clazz, BIF.class)) { 343 try { 344 bif=(BIF)clazz.newInstance(); 345 } 346 catch (Throwable t) { 347 throw new RuntimeException(t); 348 } 349 } 350 else { 351 return new BIFProxy(clazz); 352 } 353 return bif; 354 } 355 }