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 **/
019package lucee.runtime.type;
020
021import java.io.IOException;
022import java.io.ObjectInput;
023import java.io.ObjectOutput;
024import java.util.HashSet;
025import java.util.Set;
026
027import lucee.commons.lang.CFTypes;
028import lucee.commons.lang.ExceptionUtil;
029import lucee.commons.lang.ExternalizableUtil;
030import lucee.commons.lang.SizeOf;
031import lucee.runtime.PageContextImpl;
032import lucee.runtime.PageSource;
033import lucee.runtime.PageSourceImpl;
034import lucee.runtime.config.ConfigWebImpl;
035import lucee.runtime.engine.ThreadLocalPageContext;
036import lucee.runtime.engine.ThreadLocalPageSource;
037import lucee.runtime.op.Caster;
038import lucee.runtime.type.dt.TimeSpanImpl;
039import lucee.runtime.type.util.UDFUtil;
040
041public final class UDFPropertiesImpl implements UDFProperties {
042        private static final long serialVersionUID = 8679484452640746605L; // do not change
043
044        
045        public  String functionName;
046        public  int returnType;
047        public  String strReturnType;
048        public  boolean output;
049        public  Boolean bufferOutput;
050        public String hint;
051        public String displayName;
052        //public Page page;
053        public PageSource pageSource;
054        public int index;
055        public FunctionArgument[] arguments;
056        public Struct meta;
057        public String description;
058        public Boolean secureJson;
059        public Boolean verifyClient;
060        public String strReturnFormat;
061        public int returnFormat;
062        public Set<Collection.Key> argumentsSet;
063        public int access;
064        public Object cachedWithin; 
065        public Integer localMode;
066
067        /**
068         * NEVER USE THIS CONSTRUCTOR, this constructor is only for deserialize this object from stream
069         */
070        public UDFPropertiesImpl(){
071                
072        }
073        
074        public UDFPropertiesImpl(
075                PageSource pageSource,
076                FunctionArgument[] arguments,
077                        int index,
078                String functionName, 
079                String strReturnType, 
080                String strReturnFormat, 
081                boolean output,
082                int access, 
083                Boolean bufferOutput,
084                String displayName, 
085                String description, 
086                String hint, 
087                Boolean secureJson,
088                Boolean verifyClient,
089                Object cachedWithin,
090                Integer localMode,
091                StructImpl meta) {
092                this(pageSource,arguments,index,functionName,CFTypes.toShortStrict(strReturnType,CFTypes.TYPE_UNKNOW),strReturnType,strReturnFormat,output,access
093                                ,bufferOutput,displayName,description,hint,secureJson,verifyClient,cachedWithin,localMode,meta);
094                
095        }
096        
097        public UDFPropertiesImpl(
098                PageSource pageSource,
099                FunctionArgument[] arguments,
100                        int index,
101                String functionName, 
102                short returnType, 
103                String strReturnFormat, 
104                boolean output, 
105                int access, 
106                Boolean bufferOutput,
107                String displayName, 
108                String description, 
109                String hint, 
110                Boolean secureJson,
111                Boolean verifyClient,
112                Object cachedWithin,
113                Integer localMode,
114                StructImpl meta) {
115                this(pageSource,arguments,index,functionName,returnType,CFTypes.toString(returnType,"any"),strReturnFormat,output,access
116                                ,bufferOutput,displayName,description,hint,secureJson,verifyClient,cachedWithin,localMode,meta);
117        }
118
119        public UDFPropertiesImpl(
120                PageSource pageSource,
121                FunctionArgument[] arguments,
122                        int index,
123                String functionName, 
124                short returnType, 
125                String strReturnFormat, 
126                boolean output, 
127                int access) {
128                this(pageSource, arguments, index, functionName, returnType,strReturnFormat, output, access, null,
129                                "","", "", null, null, null, null, null);
130        }
131        
132
133        private UDFPropertiesImpl(
134                PageSource pageSource,
135                FunctionArgument[] arguments,
136                        int index,
137                String functionName, 
138                short returnType, 
139                String strReturnType, 
140                String strReturnFormat, 
141                boolean output, 
142                int access, 
143                Boolean bufferOutput,
144                String displayName, 
145                String description, 
146                String hint, 
147                Boolean secureJson,
148                Boolean verifyClient,
149                Object cachedWithin,
150                Integer localMode,
151                StructImpl meta) {
152                
153                // this happens when a arcive is based on older source code
154                if(pageSource==null){
155                        pageSource = ThreadLocalPageSource.get();
156                }
157                
158                
159                if(arguments.length>0){
160                        this.argumentsSet=new HashSet<Collection.Key>();
161                        for(int i=0;i<arguments.length;i++){
162                                argumentsSet.add(arguments[i].getName());
163                        }
164                }
165                else this.argumentsSet=null;
166                
167                this.arguments = arguments;
168                this.description = description;
169                this.displayName = displayName;
170                this.functionName = functionName;
171                this.hint = hint;
172                this.index = index;
173                this.meta = meta;
174                this.output = output;
175                this.bufferOutput = bufferOutput;
176                this.pageSource = pageSource;
177                
178                this.strReturnType=strReturnType;
179                this.returnType=returnType;
180                
181                this.strReturnFormat=strReturnFormat;
182                this.returnFormat=UDFUtil.toReturnFormat(strReturnFormat,-1);
183                
184                this.secureJson = secureJson;
185                this.verifyClient = verifyClient;
186                this.access = access;
187                this.cachedWithin=cachedWithin instanceof Long?TimeSpanImpl.fromMillis(((Long)cachedWithin).longValue()):cachedWithin; 
188                this.localMode=localMode;
189        }
190        
191        
192        /**
193         * @deprecated only supported for old compile templates in .ra archives
194         * */
195        public UDFPropertiesImpl(
196                PageSource pageSource,
197                FunctionArgument[] arguments,
198                        int index,
199                String functionName, 
200                String strReturnType, 
201                String strReturnFormat, 
202                boolean output,
203                int access, 
204                Boolean bufferOutput,
205                String displayName, 
206                String description, 
207                String hint, 
208                Boolean secureJson,
209                Boolean verifyClient,
210                long cachedWithin,
211                Integer localMode,
212                StructImpl meta) {
213                this(pageSource, arguments, index, functionName, strReturnType, strReturnFormat, output, access, bufferOutput, displayName, description, hint, secureJson, verifyClient, cachedWithin==0?null:TimeSpanImpl.fromMillis(cachedWithin), localMode, meta);
214        }
215        
216        /**
217         * @deprecated only supported for old compile templates in .ra archives
218         * */
219        public UDFPropertiesImpl(
220                PageSource pageSource,
221                FunctionArgument[] arguments,
222                        int index,
223                String functionName, 
224                short returnType, 
225                String strReturnFormat, 
226                boolean output, 
227                int access, 
228                Boolean bufferOutput,
229                String displayName, 
230                String description, 
231                String hint, 
232                Boolean secureJson,
233                Boolean verifyClient,
234                long cachedWithin,
235                Integer localMode,
236                StructImpl meta) {
237                
238                this(pageSource, arguments, index, functionName, returnType, strReturnFormat, output, access, bufferOutput, displayName, description, hint, secureJson, verifyClient,cachedWithin==0?null:TimeSpanImpl.fromMillis(cachedWithin), localMode, meta); 
239        }
240        
241        /**
242         * @deprecated only supported for old compile templates in .ra archives
243         * */
244        public UDFPropertiesImpl(
245                PageSource pageSource,
246                FunctionArgument[] arguments,
247                        int index,
248                String functionName, 
249                String strReturnType, 
250                String strReturnFormat, 
251                boolean output,
252                int access, 
253                String displayName, 
254                String description, 
255                String hint, 
256                Boolean secureJson,
257                Boolean verifyClient,
258                long cachedWithin,
259                StructImpl meta) {
260                this(pageSource, arguments, index, functionName, strReturnType, strReturnFormat, 
261                                output,  access, null,displayName, description, hint, secureJson, verifyClient, cachedWithin,null, meta);
262        }
263        
264        /**
265         * @deprecated only supported for old compile templates in .ra archives
266         * */
267        public UDFPropertiesImpl(
268                PageSource pageSource,
269                FunctionArgument[] arguments,
270                        int index,
271                String functionName, 
272                short returnType, 
273                String strReturnFormat, 
274                boolean output, 
275                int access, 
276                String displayName, 
277                String description, 
278                String hint, 
279                Boolean secureJson,
280                Boolean verifyClient,
281                long cachedWithin,
282                StructImpl meta) {
283                this(pageSource, arguments, index, functionName, returnType, strReturnFormat, 
284                                output,  access,null, displayName, description, hint, secureJson, verifyClient, cachedWithin, null, meta);
285        }
286
287        @Override
288        public long sizeOf() {
289                return 
290                SizeOf.size(functionName)+
291                SizeOf.size(returnType)+
292                SizeOf.size(strReturnType)+
293                SizeOf.size(output)+
294                SizeOf.size(bufferOutput)+
295                SizeOf.size(hint)+
296                SizeOf.size(index)+
297                SizeOf.size(displayName)+
298                SizeOf.size(arguments)+
299                SizeOf.size(meta)+
300                SizeOf.size(description)+
301                SizeOf.size(secureJson)+
302                SizeOf.size(verifyClient)+
303                SizeOf.size(strReturnFormat)+
304                SizeOf.size(returnFormat)+
305                SizeOf.size(cachedWithin);
306        }
307        
308
309         /**
310         * @return the access
311         */
312        public int getAccess() {
313                return access;
314        }
315
316        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
317                try {
318                        PageContextImpl pc = (PageContextImpl) ThreadLocalPageContext.get();
319                        ConfigWebImpl cw = (ConfigWebImpl) ThreadLocalPageContext.getConfig(pc);
320                        String path=ExternalizableUtil.readString(in);
321                        pageSource=PageSourceImpl.best(cw.getPageSources(pc,null, path, false,true,true));
322                        
323                } 
324                catch (Throwable e) {
325                        ExceptionUtil.rethrowIfNecessary(e);
326                        e.printStackTrace();
327                        throw ExceptionUtil.toIOException(e);
328                }
329                
330                arguments=(FunctionArgument[]) in.readObject();
331                access = in.readInt();
332                index = in.readInt();
333                returnFormat = in.readInt();
334                returnType = in.readInt();
335                description = ExternalizableUtil.readString(in);
336                displayName = ExternalizableUtil.readString(in);
337                functionName = ExternalizableUtil.readString(in);
338                hint = ExternalizableUtil.readString(in);
339                meta = (Struct) in.readObject();
340                output = in.readBoolean();
341                bufferOutput = ExternalizableUtil.readBoolean(in);
342                secureJson = ExternalizableUtil.readBoolean(in);
343                strReturnFormat = ExternalizableUtil.readString(in);
344                strReturnType = ExternalizableUtil.readString(in);
345                verifyClient = ExternalizableUtil.readBoolean(in);
346                cachedWithin = ExternalizableUtil.readString(in);
347                int tmp=in.readInt();
348                localMode=tmp==-1?null:tmp;
349                
350                if(arguments!=null && arguments.length>0){
351                        this.argumentsSet=new HashSet<Collection.Key>();
352                        for(int i=0;i<arguments.length;i++){
353                                argumentsSet.add(arguments[i].getName());
354                        }
355                }
356                
357        }
358
359
360        public void writeExternal(ObjectOutput out) throws IOException {
361
362                out.writeObject(pageSource.getFullRealpath());
363                out.writeObject(arguments);
364                out.writeInt(access);
365                out.writeInt(index);
366                out.writeInt(returnFormat);
367                out.writeInt(returnType);
368                ExternalizableUtil.writeString(out,description);
369                ExternalizableUtil.writeString(out,displayName);
370                ExternalizableUtil.writeString(out,functionName);
371                ExternalizableUtil.writeString(out,hint);
372                out.writeObject(meta);
373                out.writeBoolean(output);
374                ExternalizableUtil.writeBoolean(out,bufferOutput);
375                ExternalizableUtil.writeBoolean(out,secureJson);
376                ExternalizableUtil.writeString(out,strReturnFormat);
377                ExternalizableUtil.writeString(out,strReturnType);
378                ExternalizableUtil.writeBoolean(out,verifyClient);
379                ExternalizableUtil.writeString(out,Caster.toString(cachedWithin,null));
380                out.writeInt(localMode==null?-1:localMode.intValue());
381        }
382
383
384
385
386}