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.ClassException;
008    import railo.commons.lang.ClassUtil;
009    import railo.commons.lang.Md5;
010    import railo.runtime.exp.TemplateException;
011    import railo.transformer.cfml.evaluator.FunctionEvaluator;
012    import railo.transformer.library.tag.TagLib;
013    
014    
015    
016    /**
017     * Eine FunctionLibFunction repr�sentiert eine einzelne Funktion innerhalb einer FLD.
018     */
019    public final class FunctionLibFunction {
020            
021            /**
022             * Dynamischer Argument Typ
023             */
024            public static final int ARG_DYNAMIC = 0;
025            /**
026             * statischer Argument Typ
027             */
028            public static final int ARG_FIX = 1;
029    
030             
031            private FunctionLib functionLib;
032            private String name;
033            private ArrayList<FunctionLibFunctionArg> argument=new ArrayList<FunctionLibFunctionArg>();
034            
035            private int argMin=0;
036            private int argMax=-1;
037            private int argType=ARG_FIX;
038            
039    
040            private String strReturnType;
041    
042            private String cls="";
043            private Class clazz;
044            private String description;
045            private boolean hasDefaultValues;
046            private FunctionEvaluator eval;
047            private String tteClass;        
048            private short status=TagLib.STATUS_IMPLEMENTED;
049    
050            
051            /**
052             * Gesch�tzer Konstruktor ohne Argumente.
053             */
054            public FunctionLibFunction() {
055            }
056            public FunctionLibFunction(FunctionLib functionLib) {
057                            this.functionLib=functionLib;
058            }
059            
060            /**
061             * Gibt den Namen der Funktion zur�ck.
062             * @return name Name der Funktion.
063             */
064            public String getName() {
065                    return name;
066            }
067            
068            /**
069            * Gibt alle Argumente einer Funktion als ArrayList zur�ck.
070            * @return Argumente der Funktion.
071            */
072       public ArrayList<FunctionLibFunctionArg> getArg() {
073               return argument;
074       }
075    
076            /**
077             * Gibt zur�ck wieviele Argumente eine Funktion minimal haben muss.
078             * @return Minimale Anzahl Argumente der Funktion.
079             */
080            public int getArgMin() {
081                    return argMin;
082            }
083            
084            /**
085             * Gibt zur�ck wieviele Argumente eine Funktion minimal haben muss.
086             * @return Maximale Anzahl Argumente der Funktion.
087             */
088            public int getArgMax() {
089                    return argMax;
090            }
091            
092            /**
093             * @return the status (TagLib.,TagLib.STATUS_IMPLEMENTED,TagLib.STATUS_DEPRECATED,TagLib.STATUS_UNIMPLEMENTED)
094             */
095            public short getStatus() {
096                    return status;
097            }
098    
099    
100            /**
101             * @param status the status to set (TagLib.,TagLib.STATUS_IMPLEMENTED,TagLib.STATUS_DEPRECATED,TagLib.STATUS_UNIMPLEMENTED)
102             */
103            public void setStatus(short status) {
104                    this.status = status;
105            }
106            
107            
108            /**
109             * Gibt die argument art zur�ck.
110             * @return argument art
111             */
112            public int getArgType() {
113                    return argType;
114            }
115            
116            /**
117             * Gibt die argument art als String zur�ck.
118             * @return argument art
119             */
120            public String getArgTypeAsString() {
121                    if(argType==ARG_DYNAMIC) return "dynamic";
122                    return "fixed";
123            }
124    
125            /**
126             * Gibt zur�ck von welchem Typ der R�ckgabewert dieser Funktion sein muss (query, string, struct, number usw.).
127             * @return Typ des R�ckgabewert.
128             */
129            public String getReturnTypeAsString() {
130                    return strReturnType;
131            }
132    
133            /**
134             * Gibt die Klassendefinition als Zeichenkette zur�ck, welche diese Funktion implementiert.
135             * @return Klassendefinition als Zeichenkette.
136             */
137            public String getCls() {
138                    return cls;
139            }
140    
141            /**
142             * Gibt die Klasse zur�ck, welche diese Funktion implementiert.
143             * @return Klasse der Function.
144             */
145            public Class getCazz() {
146                    if(clazz==null) {
147                            clazz=ClassUtil.loadClass(cls,(Class)null);
148                            /*try {
149                                    clazz=Class.orName(cls);
150                            } catch (ClassNotFoundException e) {
151                                    
152                            }*/
153                    }
154                    return clazz;
155            }
156    
157            /**
158             * Gibt die Beschreibung der Funktion zur�ck.
159             * @return String
160             */
161            public String getDescription() {
162                    return description;
163            }
164    
165            /**
166             * Gibt die FunctionLib zur�ck, zu der die Funktion geh�rt.
167             * @return Zugeh�rige FunctionLib.
168             */
169            public FunctionLib getFunctionLib() {
170                    return functionLib;
171            }
172    
173            /**
174             * Setzt den Namen der Funktion.
175             * @param name Name der Funktion.
176             */
177            public void setName(String name) {
178                    this.name = name.toLowerCase();
179            }       
180    
181            /**
182             * F�gt der Funktion ein Argument hinzu.
183             * @param arg Argument zur Funktion.
184             */
185            public void addArg(FunctionLibFunctionArg arg) {
186                    arg.setFunction(this);
187                    argument.add(arg); 
188                    if(arg.getDefaultValue()!=null)
189                            hasDefaultValues=true;
190            }
191    
192            /**
193             * F�gt der Funktion ein Argument hinzu, alias f�r addArg.
194             * @param arg Argument zur Funktion.
195             */
196            public void setArg(FunctionLibFunctionArg arg) {
197                    addArg(arg);
198            }
199    
200    
201            /**
202             * Setzt wieviele Argumente eine Funktion minimal haben muss.
203             * @param argMin Minimale Anzahl Argumente der Funktion.
204             */
205            public void setArgMin(int argMin) {
206                    this.argMin = argMin;
207            }
208            
209            /**
210             * Setzt wieviele Argumente eine Funktion minimal haben muss.
211             * @param argMax Maximale Anzahl Argumente der Funktion.
212             */
213            public void setArgMax(int argMax) {
214                    this.argMax = argMax;
215            }
216    
217            /**
218             * Setzt den R�ckgabewert der Funktion (query,array,string usw.)
219             * @param value
220             */
221            public void setReturn(String value) {
222                    strReturnType=value;
223            }
224    
225            /**
226             * Setzt die Klassendefinition als Zeichenkette, welche diese Funktion implementiert.
227             * @param value Klassendefinition als Zeichenkette.
228             */
229            public void setCls(String value) {
230                    cls+=value;
231                    
232            }
233    
234            /**
235             * Setzt die Beschreibung der Funktion.
236             * @param description Beschreibung der Funktion.
237             */
238            public void setDescription(String description) {
239                    this.description = description;
240            }
241    
242            /**
243             * Setzt die zugeh�rige FunctionLib.
244             * @param functionLib Zugeh�rige FunctionLib.
245             */
246            public void setFunctionLib(FunctionLib functionLib) {
247                    this.functionLib=functionLib;
248            }
249    
250            /**
251             * sets the argument type of the function
252             * @param argType
253             */
254            public void setArgType(int argType) {
255                    this.argType=argType;
256            }
257            
258    
259            public String getHash() {
260                    StringBuffer sb=new StringBuffer();
261                    sb.append(this.getArgMax());
262                    sb.append(this.getArgMin());
263                    sb.append(this.getArgType());
264                    sb.append(this.getArgTypeAsString());
265                    sb.append(this.getCls());
266                    sb.append(this.getName());
267                    sb.append(this.getReturnTypeAsString());
268                    
269                    Iterator it = this.getArg().iterator();
270                    FunctionLibFunctionArg arg;
271                    while(it.hasNext()){
272                            arg=(FunctionLibFunctionArg) it.next();
273                            sb.append(arg.getHash());
274                    }
275                    
276                    try {
277                            return Md5.getDigestAsString(sb.toString());
278                    } catch (IOException e) {
279                            return "";
280                    }
281            }
282            public boolean hasDefaultValues() {
283                    return hasDefaultValues;
284            }
285    
286            public boolean hasTteClass() {
287                    return tteClass !=null && tteClass.length()>0;
288            }
289            
290            public FunctionEvaluator getEvaluator() throws TemplateException {
291                    if(!hasTteClass()) return null;
292                    if(eval!=null) return eval;
293                    try {
294                            eval = (FunctionEvaluator) ClassUtil.loadInstance(tteClass);
295                    } 
296                    catch (ClassException e) {
297                            throw new TemplateException(e.getMessage());
298                    } 
299                    return eval;
300            }
301            public void setTteClass(String tteClass) {
302                    this.tteClass=tteClass;
303            }
304    }