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.config;
020
021import static lucee.runtime.db.DatasourceManagerImpl.QOQ_DATASOURCE_NAME;
022
023import java.io.IOException;
024import java.io.PrintWriter;
025import java.net.URL;
026import java.nio.charset.Charset;
027import java.util.ArrayList;
028import java.util.Arrays;
029import java.util.Collections;
030import java.util.Comparator;
031import java.util.HashMap;
032import java.util.Iterator;
033import java.util.List;
034import java.util.Locale;
035import java.util.Map;
036import java.util.Map.Entry;
037import java.util.TimeZone;
038
039import lucee.commons.digest.Hash;
040import lucee.commons.io.CharsetUtil;
041import lucee.commons.io.SystemUtil;
042import lucee.commons.io.log.LegacyLogger;
043import lucee.commons.io.log.Log;
044import lucee.commons.io.log.LogAndSource;
045import lucee.commons.io.log.LoggerAndSourceData;
046import lucee.commons.io.log.log4j.LogAdapter;
047import lucee.commons.io.log.log4j.layout.ClassicLayout;
048import lucee.commons.io.res.Resource;
049import lucee.commons.io.res.ResourceProvider;
050import lucee.commons.io.res.Resources;
051import lucee.commons.io.res.ResourcesImpl;
052import lucee.commons.io.res.filter.ExtensionResourceFilter;
053import lucee.commons.io.res.type.compress.Compress;
054import lucee.commons.io.res.type.compress.CompressResource;
055import lucee.commons.io.res.type.compress.CompressResourceProvider;
056import lucee.commons.io.res.util.ResourceClassLoader;
057import lucee.commons.io.res.util.ResourceUtil;
058import lucee.commons.lang.ClassException;
059import lucee.commons.lang.ClassLoaderHelper;
060import lucee.commons.lang.ClassUtil;
061import lucee.commons.lang.ExceptionUtil;
062import lucee.commons.lang.Md5;
063import lucee.commons.lang.PhysicalClassLoader;
064import lucee.commons.lang.StringUtil;
065import lucee.commons.lang.SystemOut;
066import lucee.commons.net.IPRange;
067import lucee.loader.engine.CFMLEngine;
068import lucee.runtime.CFMLFactory;
069import lucee.runtime.Component;
070import lucee.runtime.Mapping;
071import lucee.runtime.MappingImpl;
072import lucee.runtime.Page;
073import lucee.runtime.PageContext;
074import lucee.runtime.PageContextImpl;
075import lucee.runtime.PageSource;
076import lucee.runtime.PageSourceImpl;
077import lucee.runtime.cache.CacheConnection;
078import lucee.runtime.cfx.CFXTagPool;
079import lucee.runtime.cfx.customtag.CFXTagPoolImpl;
080import lucee.runtime.component.ImportDefintion;
081import lucee.runtime.component.ImportDefintionImpl;
082import lucee.runtime.customtag.InitFile;
083import lucee.runtime.db.DataSource;
084import lucee.runtime.db.DatasourceConnectionPool;
085import lucee.runtime.dump.DumpWriter;
086import lucee.runtime.dump.DumpWriterEntry;
087import lucee.runtime.dump.HTMLDumpWriter;
088import lucee.runtime.engine.ExecutionLogFactory;
089import lucee.runtime.engine.ThreadLocalPageContext;
090import lucee.runtime.exp.ApplicationException;
091import lucee.runtime.exp.DatabaseException;
092import lucee.runtime.exp.DeprecatedException;
093import lucee.runtime.exp.ExpressionException;
094import lucee.runtime.exp.PageException;
095import lucee.runtime.exp.PageRuntimeException;
096import lucee.runtime.exp.SecurityException;
097import lucee.runtime.extension.Extension;
098import lucee.runtime.extension.ExtensionProvider;
099import lucee.runtime.extension.ExtensionProviderImpl;
100import lucee.runtime.functions.system.ContractPath;
101import lucee.runtime.listener.AppListenerUtil;
102import lucee.runtime.listener.ApplicationContext;
103import lucee.runtime.listener.ApplicationListener;
104import lucee.runtime.net.amf.AMFCaster;
105import lucee.runtime.net.amf.ClassicAMFCaster;
106import lucee.runtime.net.amf.ModernAMFCaster;
107import lucee.runtime.net.mail.Server;
108import lucee.runtime.net.ntp.NtpClient;
109import lucee.runtime.net.proxy.ProxyData;
110import lucee.runtime.op.Caster;
111import lucee.runtime.op.Duplicator;
112import lucee.runtime.orm.ORMConfiguration;
113import lucee.runtime.orm.ORMEngine;
114import lucee.runtime.rest.RestSettingImpl;
115import lucee.runtime.rest.RestSettings;
116import lucee.runtime.schedule.Scheduler;
117import lucee.runtime.schedule.SchedulerImpl;
118import lucee.runtime.search.SearchEngine;
119import lucee.runtime.security.SecurityManager;
120import lucee.runtime.spooler.SpoolerEngine;
121import lucee.runtime.type.Collection.Key;
122import lucee.runtime.type.Struct;
123import lucee.runtime.type.StructImpl;
124import lucee.runtime.type.UDF;
125import lucee.runtime.type.dt.TimeSpan;
126import lucee.runtime.type.dt.TimeSpanImpl;
127import lucee.runtime.type.scope.Cluster;
128import lucee.runtime.type.scope.ClusterNotSupported;
129import lucee.runtime.type.scope.Undefined;
130import lucee.runtime.type.util.KeyConstants;
131import lucee.runtime.video.VideoExecuterNotSupported;
132import lucee.transformer.library.function.FunctionLib;
133import lucee.transformer.library.function.FunctionLibException;
134import lucee.transformer.library.function.FunctionLibFactory;
135import lucee.transformer.library.function.FunctionLibFunction;
136import lucee.transformer.library.function.FunctionLibFunctionArg;
137import lucee.transformer.library.tag.TagLib;
138import lucee.transformer.library.tag.TagLibException;
139import lucee.transformer.library.tag.TagLibFactory;
140import lucee.transformer.library.tag.TagLibTag;
141import lucee.transformer.library.tag.TagLibTagAttr;
142
143import org.apache.commons.collections.map.ReferenceMap;
144import org.apache.log4j.Layout;
145import org.apache.log4j.Level;
146import org.apache.log4j.Logger;
147import org.apache.log4j.PatternLayout;
148import org.w3c.dom.Document;
149import org.w3c.dom.Element;
150
151import flex.messaging.config.ConfigMap;
152
153
154/**
155 * Hold the definitions of the lucee configuration.
156 */
157public abstract class ConfigImpl implements Config {
158
159        public static final short INSPECT_UNDEFINED = 4;// FUTURE move to Config; Hibernate Extension has hardcoded this 4, do not change!!!!
160
161
162        public static final int CLIENT_BOOLEAN_TRUE = 0;
163        public static final int CLIENT_BOOLEAN_FALSE = 1;
164        public static final int SERVER_BOOLEAN_TRUE = 2;
165        public static final int SERVER_BOOLEAN_FALSE = 3;
166
167        public static final int DEBUG_DATABASE = 1;
168        public static final int DEBUG_EXCEPTION = 2;
169        public static final int DEBUG_TRACING = 4;
170        public static final int DEBUG_TIMER = 8;
171        public static final int DEBUG_IMPLICIT_ACCESS = 16;
172        public static final int DEBUG_QUERY_USAGE = 32;
173        public static final int DEBUG_DUMP = 64;
174        
175        
176        
177        
178        public static final ExtensionProvider[] LUCEE_EXTENSION_PROVIDERS = new ExtensionProviderImpl[]{
179                new ExtensionProviderImpl("http://extension.lucee.org/ExtensionProvider.cfc",true)
180        };
181        private static final Extension[] EXTENSIONS_EMPTY = new Extension[0];
182        
183        public static final int AMF_CONFIG_TYPE_XML = 1;
184        public static final int AMF_CONFIG_TYPE_MANUAL = 2;
185
186        public static final int MODE_CUSTOM = 1;
187        public static final int MODE_STRICT = 2;
188        
189
190        public static final int CFML_WRITER_REFULAR=1;
191        public static final int CFML_WRITER_WS=2;
192        public static final int CFML_WRITER_WS_PREF=3;
193
194
195        public static final String DEFAULT_STORAGE_SESSION = "memory";
196        public static final String DEFAULT_STORAGE_CLIENT = "cookie";
197        
198        
199        private int mode=MODE_CUSTOM;
200
201        private PhysicalClassLoader rpcClassLoader;
202        private Map<String,DataSource> datasources=new HashMap<String,DataSource>();
203        private Map<String,CacheConnection> caches=new HashMap<String, CacheConnection>();
204
205        private CacheConnection defaultCacheFunction=null;
206        private CacheConnection defaultCacheObject=null;
207        private CacheConnection defaultCacheTemplate=null;
208        private CacheConnection defaultCacheQuery=null;
209        private CacheConnection defaultCacheResource=null;
210        private CacheConnection defaultCacheInclude=null;
211
212        private String cacheDefaultConnectionNameFunction=null;
213        private String cacheDefaultConnectionNameObject=null;
214        private String cacheDefaultConnectionNameTemplate=null;
215        private String cacheDefaultConnectionNameQuery=null;
216        private String cacheDefaultConnectionNameResource=null;
217        private String cacheDefaultConnectionNameInclude=null;
218        
219    private TagLib[] tlds=new TagLib[1];
220    private FunctionLib[] flds=new FunctionLib[1];
221    private FunctionLib combinedFLDs;
222
223    private short type=SCOPE_STANDARD;
224    private boolean _allowImplicidQueryCall=true;
225    private boolean _mergeFormAndURL=false;
226
227        private Map<String,LoggerAndSourceData> loggers=new HashMap<String, LoggerAndSourceData>();
228        
229    private int _debug;
230    private int debugLogOutput=SERVER_BOOLEAN_FALSE;
231    private int debugOptions=0;
232
233    private boolean suppresswhitespace = false;
234    private boolean suppressContent = false;
235    private boolean showVersion = false;
236    
237        private Resource tempDirectory;
238    private TimeSpan clientTimeout=new TimeSpanImpl(90,0,0,0);
239    private TimeSpan sessionTimeout=new TimeSpanImpl(0,0,30,0);
240    private TimeSpan applicationTimeout=new TimeSpanImpl(1,0,0,0);
241    private TimeSpan requestTimeout=new TimeSpanImpl(0,0,0,30);
242    
243    private boolean sessionManagement=true;  
244    private boolean clientManagement=false;
245    private boolean clientCookies=true; 
246    private boolean domainCookies=false;
247
248    private Resource configFile;
249    private Resource configDir;
250        private String sessionStorage=DEFAULT_STORAGE_SESSION;
251        private String clientStorage=DEFAULT_STORAGE_CLIENT;
252        
253
254    private long loadTime;
255
256    private int spoolInterval=30;
257    private boolean spoolEnable=true;
258
259    private Server[] mailServers;
260
261    private int mailTimeout=30;
262
263    private TimeZone timeZone;
264
265    private String timeServer="";
266    private boolean useTimeServer=true;
267
268    private long timeOffset;
269
270    private SearchEngine searchEngine;
271
272    private Locale locale;
273
274    private boolean psq=false;
275    private boolean debugShowUsage;
276
277    private Map<String,String> errorTemplates=new HashMap<String,String>();
278
279    protected Password password;
280
281    private Mapping[] mappings=new Mapping[0];
282    private Mapping[] customTagMappings=new Mapping[0];
283    private Mapping[] componentMappings=new Mapping[0];
284
285    private SchedulerImpl scheduler;
286    
287    private CFXTagPool cfxTagPool;
288
289    private PageSource baseComponentPageSource;
290    private String baseComponentTemplate;
291    private boolean restList=false;
292    
293    private short clientType=CLIENT_SCOPE_TYPE_COOKIE;
294    
295    private String componentDumpTemplate;
296    private int componentDataMemberDefaultAccess=Component.ACCESS_PRIVATE;
297    private boolean triggerComponentDataMember=false;
298    
299    
300    private short sessionType=SESSION_TYPE_CFML;
301
302    private Resource deployDirectory;
303
304    private short compileType=RECOMPILE_NEVER;
305    
306    private Charset resourceCharset=SystemUtil.getCharset();
307    private Charset templateCharset=SystemUtil.getCharset();
308    private Charset webCharset=CharsetUtil.UTF8;
309
310        private String mailDefaultEncoding = "UTF-8";
311        
312        private Resource tldFile;
313        private Resource fldFile;
314
315        private Resources resources=new ResourcesImpl();
316
317        private ApplicationListener applicationListener;
318        
319        private int scriptProtect=ApplicationContext.SCRIPT_PROTECT_ALL;
320
321        private ProxyData proxy =null;
322
323
324        private Resource clientScopeDir;
325        private Resource sessionScopeDir;
326        private long clientScopeDirSize=1024*1024*10;
327        private long sessionScopeDirSize=1024*1024*10;
328
329        private Resource cacheDir;
330        private long cacheDirSize=1024*1024*10;
331
332
333        private boolean useComponentShadow=true;
334
335        
336        private PrintWriter out=SystemUtil.getPrintWriter(SystemUtil.OUT);
337        private PrintWriter err=SystemUtil.getPrintWriter(SystemUtil.ERR);
338
339        private DatasourceConnectionPool pool=new DatasourceConnectionPool();
340
341        private boolean doCustomTagDeepSearch=false;
342        private boolean doComponentTagDeepSearch=false;
343
344        private double version=1.0D;
345
346        private boolean closeConnection=false;
347        private boolean contentLength=true;
348        private boolean allowCompression=false;
349        
350
351        private boolean doLocalCustomTag=true; 
352
353        private Struct constants=null;
354
355        private RemoteClient[] remoteClients;
356
357        private SpoolerEngine remoteClientSpoolerEngine;
358
359        private Resource remoteClientDirectory;
360
361        private boolean allowURLRequestTimeout=false;
362        private CFMLFactory factory;
363        private boolean errorStatusCode=true;
364        private int localMode=Undefined.MODE_LOCAL_OR_ARGUMENTS_ONLY_WHEN_EXISTS;
365        
366        private String id;
367        private String securityToken;
368        private String securityKey;
369        private ExtensionProvider[] extensionProviders=LUCEE_EXTENSION_PROVIDERS;
370        private Extension[] extensions=EXTENSIONS_EMPTY;
371        private boolean extensionEnabled;
372        private boolean allowRelPath=true;
373
374        private DumpWriterEntry[] dmpWriterEntries;
375        private Class clusterClass=ClusterNotSupported.class;//ClusterRemoteNotSupported.class;//
376        private Struct remoteClientUsage;
377        private Class adminSyncClass=AdminSyncNotSupported.class;
378        private AdminSync adminSync;
379        private String[] customTagExtensions=new String[]{"cfm","cfc"};
380        private Class videoExecuterClass=VideoExecuterNotSupported.class;
381        
382        protected MappingImpl tagMapping;
383        private Resource tagDirectory;
384        protected MappingImpl functionMapping;
385        private Map amfCasterArguments;
386        private Class amfCasterClass=ClassicAMFCaster.class;
387        private AMFCaster amfCaster;
388        private short inspectTemplate=INSPECT_ONCE;
389        private boolean typeChecking=true;
390        private String serial="";
391        private String cacheMD5;
392        private boolean executionLogEnabled;
393        private ExecutionLogFactory executionLogFactory;
394        private Map<String, ORMEngine> ormengines=new HashMap<String, ORMEngine>();
395        private Class<ORMEngine> ormEngineClass;
396        private ORMConfiguration ormConfig;
397        private ResourceClassLoader resourceCL;
398        
399        private ImportDefintion componentDefaultImport=new ImportDefintionImpl("org.lucee.cfml","*");
400        private boolean componentLocalSearch=true;
401        private boolean componentRootSearch=true;
402        private boolean useComponentPathCache=true;
403        private boolean useCTPathCache=true;
404        private int amfConfigType=AMF_CONFIG_TYPE_XML;
405        private lucee.runtime.rest.Mapping[] restMappings;
406        
407        protected int writerType=CFML_WRITER_REFULAR;
408        private long configFileLastModified;
409        private boolean checkForChangesInConfigFile;
410        private String apiKey=null;
411        
412        private List<Layout> consoleLayouts=new ArrayList<Layout>();
413        private List<Layout> resourceLayouts=new ArrayList<Layout>();
414
415        private Map<Key, Map<Key, Object>> tagDefaultAttributeValues;
416
417        private int queueMax=100;
418        private long queueTimeout=0;
419        private boolean queueEnable=false;
420        
421        
422        /**
423         * @return the allowURLRequestTimeout
424         */
425        public boolean isAllowURLRequestTimeout() {
426                return allowURLRequestTimeout;
427        }
428
429        /**
430         * @param allowURLRequestTimeout the allowURLRequestTimeout to set
431         */
432        public void setAllowURLRequestTimeout(boolean allowURLRequestTimeout) {
433                this.allowURLRequestTimeout = allowURLRequestTimeout;
434        }
435
436
437    @Override
438    public short getCompileType() {
439        return compileType;
440    }
441
442    @Override
443    public void reset() {
444        timeServer="";
445        componentDumpTemplate="";
446        factory.resetPageContext();
447        //resources.reset();
448        ormengines.clear();
449        compressResources.clear();
450        clearFunctionCache();
451        clearCTCache();
452        clearComponentCache();
453        //clearComponentMetadata();
454    }
455    
456    @Override
457    public void reloadTimeServerOffset() {
458        timeOffset=0;
459        if(useTimeServer && !StringUtil.isEmpty(timeServer,true)) {
460            NtpClient ntp=new NtpClient(timeServer);
461            try {
462                timeOffset=ntp.getOffset();
463            } catch (IOException e) {
464                timeOffset=0;
465            }
466        }
467    }
468
469    
470    /**
471     * private constructor called by factory method
472     * @param factory
473     * @param configDir - config directory
474     * @param configFile - config file
475     */
476    protected ConfigImpl(CFMLFactory factory,Resource configDir, Resource configFile) {
477        this(factory,configDir,configFile,
478                        loadTLDs() , 
479                        loadFLDs());
480    }
481
482
483    private static FunctionLib[] loadFLDs() {
484                try {
485                        return new FunctionLib[]{FunctionLibFactory.loadFromSystem()};
486                } catch (FunctionLibException e) {e.printStackTrace();
487                        return new FunctionLib[]{};
488                }
489        }
490
491        private static TagLib[] loadTLDs() {
492                try {
493                        return new TagLib[]{TagLibFactory.loadFromSystem()};
494                } catch (TagLibException e) {e.printStackTrace();
495                        return new TagLib[]{};
496                }
497        }
498
499        public ConfigImpl(CFMLFactory factory,Resource configDir, Resource configFile, TagLib[] tlds, FunctionLib[] flds) {
500                
501                this.configDir=configDir;
502        this.configFile=configFile;
503        this.factory=factory;
504        
505        this.tlds=duplicate(tlds,false);
506        this.flds=duplicate(flds,false);
507        }
508
509
510        private static TagLib[] duplicate(TagLib[] tlds, boolean deepCopy) {
511                TagLib[] rst = new TagLib[tlds.length];
512                for(int i=0;i<tlds.length;i++){
513                        rst[i]=tlds[i].duplicate(deepCopy);
514                }
515                return rst;
516        }
517        private static FunctionLib[] duplicate(FunctionLib[] flds, boolean deepCopy) {
518                FunctionLib[] rst = new FunctionLib[flds.length];
519                for(int i=0;i<flds.length;i++){
520                        rst[i]=flds[i].duplicate(deepCopy);
521                }
522                return rst;
523        }
524        
525        public long lastModified() {
526        return configFileLastModified;
527    }
528        
529        protected void setLastModified() {
530                this.configFileLastModified=configFile.lastModified();
531    }
532        
533
534    
535
536        @Override
537    public short getScopeCascadingType() {
538        return type;
539    }
540    
541    @Override
542    public String[] getCFMLExtensions() {
543        return Constants.CFML_EXTENSION;
544    }
545    @Override
546    public String getCFCExtension() {
547        return Constants.CFC_EXTENSION;
548    }
549
550    
551    /**
552     * return all Function Library Deskriptors
553     * @return Array of Function Library Deskriptors
554     */
555    public FunctionLib[] getFLDs() {
556        return flds;
557    }
558    
559    public FunctionLib getCombinedFLDs() {
560        if(combinedFLDs==null)combinedFLDs=FunctionLibFactory.combineFLDs(flds);
561        return combinedFLDs;
562    }
563    
564    /**
565     * return all Tag Library Deskriptors
566     * @return Array of Tag Library Deskriptors
567     */
568    public TagLib[] getTLDs()  {
569        return tlds;
570    }
571    
572    @Override
573    public boolean allowImplicidQueryCall() {
574        return _allowImplicidQueryCall;
575    }
576
577    @Override
578    public boolean mergeFormAndURL() {
579        return _mergeFormAndURL;
580    }
581    
582    @Override
583    public TimeSpan getApplicationTimeout() {
584        return applicationTimeout;
585    }
586
587    @Override
588    public TimeSpan getSessionTimeout() {
589        return sessionTimeout;
590    }
591
592    @Override
593    public TimeSpan getClientTimeout() {
594        return clientTimeout;
595    }
596    
597    @Override
598    public TimeSpan getRequestTimeout() {
599        return requestTimeout;
600    }   
601    
602    @Override
603    public boolean isClientCookies() {
604        return clientCookies;
605    }
606    
607    @Override
608    public boolean isClientManagement() {
609        return clientManagement;
610    }
611    
612    @Override
613    public boolean isDomainCookies() {
614        return domainCookies;
615    }
616    
617    @Override
618    public boolean isSessionManagement() {
619        return sessionManagement;
620    }
621    
622    @Override
623    public boolean isMailSpoolEnable() {
624        return spoolEnable;
625    }
626    
627    @Override
628    public Server[] getMailServers() {
629        if(mailServers==null) mailServers=new Server[0];
630        return mailServers;
631    }
632    
633    @Override
634    public int getMailTimeout() {
635        return mailTimeout;
636    }   
637    
638    @Override
639    public boolean getPSQL() {
640        return psq;   
641    }
642
643    @Override
644    public ClassLoader getClassLoader() {
645        ResourceClassLoader rcl = getResourceClassLoader(null);
646        if(rcl!=null) return rcl;
647        return new ClassLoaderHelper().getClass().getClassLoader();
648    }
649    public ResourceClassLoader getResourceClassLoader() {
650        if(resourceCL==null) throw new RuntimeException("no RCL defined yet!");
651        return resourceCL;   
652    }
653    public ResourceClassLoader getResourceClassLoader(ResourceClassLoader defaultValue) {
654        if(resourceCL==null) return defaultValue;
655        return resourceCL;   
656    }
657
658    @Override
659    public ClassLoader getClassLoader(Resource[] reses) throws IOException {
660        throw new RuntimeException("this method is no longer suported");
661    }
662
663    protected void setResourceClassLoader(ResourceClassLoader resourceCL) {
664        this.resourceCL=resourceCL;
665        }
666
667    @Override
668    public Locale getLocale() {
669        return locale;
670    }
671
672    @Override
673    public boolean debug() {
674        if(!(_debug==CLIENT_BOOLEAN_TRUE || _debug==SERVER_BOOLEAN_TRUE)) return false;
675        return true;
676    }
677    
678    public boolean debugLogOutput() {
679        return debug() && debugLogOutput==CLIENT_BOOLEAN_TRUE || debugLogOutput==SERVER_BOOLEAN_TRUE;
680    }
681
682    @Override
683    public Resource getTempDirectory() {
684        if(tempDirectory==null) {
685                Resource tmp = SystemUtil.getTempDirectory();
686                if(!tmp.exists()) tmp.mkdirs();
687                return tmp;
688        }
689        if(!tempDirectory.exists()) tempDirectory.mkdirs();
690        return tempDirectory;
691    }
692    
693    @Override
694    public int getMailSpoolInterval() {
695        return spoolInterval;
696    }
697
698    @Override
699    public LogAndSource getMailLogger() {
700        return new LegacyLogger( getLog("mail", true));
701        //throw new RuntimeException(new DeprecatedException("this method is no longer supported, use instead getLog"));
702    }
703    
704    @Override
705    public LogAndSource getRequestTimeoutLogger() {
706        return new LegacyLogger( getLog("requesttimeout", true));
707        //throw new RuntimeException(new DeprecatedException("this method is no longer supported, use instead getLog"));
708    }
709    
710    @Override
711    public LogAndSource getTraceLogger() {
712        return new LegacyLogger( getLog("trace", true));
713        //throw new RuntimeException(new DeprecatedException("this method is no longer supported, use instead getLog"));
714    }
715
716    @Override
717    public TimeZone getTimeZone() {
718        return timeZone;
719    }
720    
721    @Override
722    public long getTimeServerOffset() {
723        return timeOffset;
724    }
725    
726    @Override
727    public SearchEngine getSearchEngine() {
728        return searchEngine;
729    }
730    
731    /**
732     * @return return the Scheduler
733     */
734    public Scheduler getScheduler() {
735        return scheduler;
736    }
737
738    /**
739     * @return gets the password as hash
740     */
741    protected Password getPassword() {
742        return password;
743    }
744    
745    public Password isPasswordEqual(String password, boolean hashIfNecessary) {
746        if(this.password==null) return null;
747        return this.password.isEqual(this,password, hashIfNecessary);
748    }
749    
750    @Override
751    public boolean hasPassword() {
752        return password!=null;
753    }
754    
755    @Override
756    public boolean passwordEqual(String password) {
757        return isPasswordEqual(password,true)!=null;
758    }
759
760    @Override
761    public Mapping[] getMappings() {
762        return mappings;
763    }
764    
765    public lucee.runtime.rest.Mapping[] getRestMappings() {
766        if(restMappings==null) restMappings=new lucee.runtime.rest.Mapping[0];
767        return restMappings;
768    }
769  
770    protected void setRestMappings(lucee.runtime.rest.Mapping[] restMappings) {
771        
772        // make sure only one is default
773        boolean hasDefault=false;
774        lucee.runtime.rest.Mapping m;
775        for(int i=0;i<restMappings.length;i++){
776                m=restMappings[i];
777                if(m.isDefault()) {
778                        if(hasDefault) m.setDefault(false);
779                        hasDefault=true;
780                }
781        }
782        
783        this.restMappings= restMappings;
784    }
785
786
787    public PageSource getPageSource(Mapping[] mappings, String relPath,boolean onlyTopLevel) {
788        throw new PageRuntimeException(new DeprecatedException("method not supported"));
789    }
790    
791    public PageSource getPageSourceExisting(PageContext pc,Mapping[] mappings, String relPath,boolean onlyTopLevel,boolean useSpecialMappings, boolean useDefaultMapping, boolean onlyPhysicalExisting) {
792        relPath=relPath.replace('\\','/');
793        String lcRelPath = StringUtil.toLowerCase(relPath)+'/';
794        Mapping mapping;
795        PageSource ps;
796
797        if(mappings!=null){
798                for(int i=0;i<mappings.length;i++) {
799                    mapping = mappings[i];
800                    //print.err(lcRelPath+".startsWith"+(mapping.getStrPhysical()));
801                    if(lcRelPath.startsWith(mapping.getVirtualLowerCaseWithSlash(),0)) {
802                        ps= mapping.getPageSource(relPath.substring(mapping.getVirtual().length()));
803                        if(onlyPhysicalExisting) {
804                                if(ps.physcalExists())return ps;
805                        }
806                        else if(ps.exists()) return ps;
807                    }
808                }
809        }
810        
811        /// special mappings
812        if(useSpecialMappings && lcRelPath.startsWith("/mapping-",0)){
813                String virtual="/mapping-tag";
814                // tag mappings
815                Mapping[] tagMappings=(this instanceof ConfigWebImpl)?new Mapping[]{((ConfigWebImpl)this).getServerTagMapping(),getTagMapping()}:new Mapping[]{getTagMapping()};
816                if(lcRelPath.startsWith(virtual,0)){
817                        for(int i=0;i<tagMappings.length;i++) {
818                            mapping = tagMappings[i];
819                            //if(lcRelPath.startsWith(mapping.getVirtualLowerCaseWithSlash(),0)) {
820                                ps = mapping.getPageSource(relPath.substring(virtual.length()));
821                                if(onlyPhysicalExisting) {
822                                        if(ps.physcalExists())return ps;
823                                }
824                                else if(ps.exists()) return ps;
825                            //}
826                        }
827                }
828                
829                // customtag mappings
830                tagMappings=getCustomTagMappings();
831                virtual="/mapping-customtag";
832                if(lcRelPath.startsWith(virtual,0)){
833                        for(int i=0;i<tagMappings.length;i++) {
834                            mapping = tagMappings[i];
835                            //if(lcRelPath.startsWith(mapping.getVirtualLowerCaseWithSlash(),0)) {
836                                ps = mapping.getPageSource(relPath.substring(virtual.length()));
837                                if(onlyPhysicalExisting) {
838                                        if(ps.physcalExists())return ps;
839                                }
840                                else if(ps.exists()) return ps;
841                            //}
842                        }
843                }
844        }
845        
846        // component mappings (only used for gateway)
847        if(pc!=null && ((PageContextImpl)pc).isGatewayContext()) {
848                boolean isCFC=getCFCExtension().equalsIgnoreCase(ResourceUtil.getExtension(relPath, null));
849            if(isCFC) {
850                        Mapping[] cmappings = getComponentMappings();
851                        for(int i=0;i<cmappings.length;i++) {
852                                ps = cmappings[i].getPageSource(relPath);
853                        if(onlyPhysicalExisting) {
854                                if(ps.physcalExists())return ps;
855                        }
856                        else if(ps.exists()) return ps;
857                    }
858                }
859        }
860        
861        // config mappings
862        for(int i=0;i<this.mappings.length-1;i++) {
863            mapping = this.mappings[i];
864            if((!onlyTopLevel || mapping.isTopLevel()) && lcRelPath.startsWith(mapping.getVirtualLowerCaseWithSlash(),0)) {
865                ps= mapping.getPageSource(relPath.substring(mapping.getVirtual().length()));
866                if(onlyPhysicalExisting) {
867                        if(ps.physcalExists())return ps;
868                }
869                else if(ps.exists()) return ps;
870            }
871        }
872        
873        if(useDefaultMapping){
874                ps= this.mappings[this.mappings.length-1].getPageSource(relPath);
875                if(onlyPhysicalExisting) {
876                        if(ps.physcalExists())return ps;
877                }
878                else if(ps.exists()) return ps;
879        }
880        return null;
881    }
882    
883    public PageSource[] getPageSources(PageContext pc,Mapping[] mappings, String relPath,boolean onlyTopLevel,boolean useSpecialMappings, boolean useDefaultMapping) {
884        return getPageSources(pc, mappings, relPath, onlyTopLevel, useSpecialMappings, useDefaultMapping, false);
885    }
886    
887    public PageSource[] getPageSources(PageContext pc,Mapping[] mappings, String relPath,boolean onlyTopLevel,boolean useSpecialMappings, boolean useDefaultMapping, boolean useComponentMappings) {
888        relPath=relPath.replace('\\','/');
889        String lcRelPath = StringUtil.toLowerCase(relPath)+'/';
890        Mapping mapping;
891
892        PageSource ps;
893        List<PageSource> list=new ArrayList<PageSource>();
894        
895        if(mappings!=null){
896                for(int i=0;i<mappings.length;i++) {
897                    mapping = mappings[i];
898                    //print.err(lcRelPath+".startsWith"+(mapping.getStrPhysical()));
899                    if(lcRelPath.startsWith(mapping.getVirtualLowerCaseWithSlash(),0)) {
900                        list.add(mapping.getPageSource(relPath.substring(mapping.getVirtual().length())));
901                    }
902                }
903        }
904        
905        /// special mappings
906        if(useSpecialMappings && lcRelPath.startsWith("/mapping-",0)){
907                String virtual="/mapping-tag";
908                // tag mappings
909                Mapping[] tagMappings=(this instanceof ConfigWebImpl)?new Mapping[]{((ConfigWebImpl)this).getServerTagMapping(),getTagMapping()}:new Mapping[]{getTagMapping()};
910                if(lcRelPath.startsWith(virtual,0)){
911                        for(int i=0;i<tagMappings.length;i++) {
912                            ps=tagMappings[i].getPageSource(relPath.substring(virtual.length()));
913                            if(ps.exists()) list.add(ps);
914                        }
915                }
916                
917                // customtag mappings
918                tagMappings=getCustomTagMappings();
919                virtual="/mapping-customtag";
920                if(lcRelPath.startsWith(virtual,0)){
921                        for(int i=0;i<tagMappings.length;i++) {
922                            ps=tagMappings[i].getPageSource(relPath.substring(virtual.length()));
923                            if(ps.exists()) list.add(ps);
924                        }
925                }
926        }
927        
928        // component mappings (only used for gateway)
929        if(useComponentMappings || (pc!=null && ((PageContextImpl)pc).isGatewayContext())) {
930                boolean isCFC=getCFCExtension().equalsIgnoreCase(ResourceUtil.getExtension(relPath, null));
931            if(isCFC) {
932                        Mapping[] cmappings = getComponentMappings();
933                        for(int i=0;i<cmappings.length;i++) {
934                                ps=cmappings[i].getPageSource(relPath);
935                                if(ps.exists()) list.add(ps);
936                    }
937                }
938        }
939        
940        // config mappings
941        for(int i=0;i<this.mappings.length-1;i++) {
942            mapping = this.mappings[i];
943            if((!onlyTopLevel || mapping.isTopLevel()) && lcRelPath.startsWith(mapping.getVirtualLowerCaseWithSlash(),0)) {
944                list.add(mapping.getPageSource(relPath.substring(mapping.getVirtual().length())));
945            }
946        }
947        
948        if(useDefaultMapping){
949                list.add(this.mappings[this.mappings.length-1].getPageSource(relPath));
950        }
951        return list.toArray(new PageSource[list.size()]); 
952    }
953    
954    /**
955     * @param mappings
956     * @param relPath
957     * @param alsoDefaultMapping ignore default mapping (/) or not
958     * @return physical path from mapping
959     */
960    public Resource getPhysical(Mapping[] mappings, String relPath, boolean alsoDefaultMapping) {
961        throw new PageRuntimeException(new DeprecatedException("method not supported"));
962    }
963
964    public Resource[] getPhysicalResources(PageContext pc,Mapping[] mappings, String relPath,boolean onlyTopLevel,boolean useSpecialMappings, boolean useDefaultMapping) {
965        // now that archives can be used the same way as physical resources, there is no need anymore to limit to that
966        throw new PageRuntimeException(new DeprecatedException("method not supported"));
967    }
968    
969
970    public Resource getPhysicalResourceExisting(PageContext pc,Mapping[] mappings, String relPath,boolean onlyTopLevel,boolean useSpecialMappings, boolean useDefaultMapping) {
971        // now that archives can be used the same way as physical resources, there is no need anymore to limit to that
972        throw new PageRuntimeException(new DeprecatedException("method not supported"));
973    }
974
975    public PageSource toPageSource(Mapping[] mappings, Resource res,PageSource defaultValue) {
976        Mapping mapping;
977        String path;
978        
979        // app-cfc mappings
980        if(mappings!=null){
981            for(int i=0;i<mappings.length;i++) {
982                mapping = mappings[i];
983                
984            // Physical
985               if(mapping.hasPhysical()) {
986                path=ResourceUtil.getPathToChild(res, mapping.getPhysical());
987                   if(path!=null) {
988                        return mapping.getPageSource(path);
989                   }
990               }
991           // Archive
992               if(mapping.hasArchive() && res.getResourceProvider() instanceof CompressResourceProvider) {
993                   Resource archive = mapping.getArchive();
994                   CompressResource cr = ((CompressResource) res);
995                   if(archive.equals(cr.getCompressResource())) {
996                           return mapping.getPageSource(cr.getCompressPath());
997                   }
998               }
999            }
1000        }
1001        
1002        // config mappings
1003        for(int i=0;i<this.mappings.length;i++) {
1004            mapping = this.mappings[i];
1005                
1006         // Physical
1007            if(mapping.hasPhysical()) {
1008                path=ResourceUtil.getPathToChild(res, mapping.getPhysical());
1009                if(path!=null) {
1010                        return mapping.getPageSource(path);
1011                }
1012            }
1013        // Archive
1014            if(mapping.hasArchive() && res.getResourceProvider() instanceof CompressResourceProvider) {
1015                        Resource archive = mapping.getArchive();
1016                        CompressResource cr = ((CompressResource) res);
1017                        if(archive.equals(cr.getCompressResource())) {
1018                                return mapping.getPageSource(cr.getCompressPath());
1019                        }
1020            }
1021        }
1022        
1023    // map resource to root mapping when same filesystem
1024        Mapping rootMapping = this.mappings[this.mappings.length-1];
1025        Resource root;
1026        if(rootMapping.hasPhysical() && 
1027                        res.getResourceProvider().getScheme().equals((root=rootMapping.getPhysical()).getResourceProvider().getScheme())) {
1028                
1029                String relpath="";
1030                while(root!=null && !ResourceUtil.isChildOf(res, root)){
1031                        root=root.getParentResource();
1032                        relpath+="../";
1033                }
1034                String p2c=ResourceUtil.getPathToChild(res,root);
1035                if(StringUtil.startsWith(p2c, '/') || StringUtil.startsWith(p2c, '\\') )
1036                        p2c=p2c.substring(1);
1037                relpath+=p2c;
1038                
1039                return rootMapping.getPageSource(relpath);
1040                
1041        }
1042        // MUST better impl than this
1043        if(this instanceof ConfigWebImpl) {
1044                Resource parent = res.getParentResource();
1045                if(parent!=null && !parent.equals(res)) {
1046                        Mapping m = ((ConfigWebImpl)this).getApplicationMapping("application","/", parent.getAbsolutePath(),null,true,false);
1047                        return m.getPageSource(res.getName());
1048                }
1049        }
1050        
1051                
1052     // Archive
1053        // MUST check archive
1054        return defaultValue;
1055    }
1056    
1057    @Override
1058    public Resource getConfigDir() {
1059        return configDir;
1060    }
1061    
1062    @Override
1063    public Resource getConfigFile() {
1064        return configFile;
1065    }
1066
1067    @Override
1068    public LogAndSource getScheduleLogger() {
1069        return new LegacyLogger( getLog("scheduler", true));
1070    }
1071    
1072    @Override
1073    public LogAndSource getApplicationLogger() {
1074        return new LegacyLogger( getLog("application", true));
1075    }
1076    
1077    
1078    
1079    /**
1080     * sets the password
1081     * @param password
1082     */
1083    protected void setPassword(Password password) {
1084        this.password=password;
1085    }
1086
1087    /**
1088     * set how lucee cascade scopes
1089     * @param type cascading type
1090     */
1091    protected void setScopeCascadingType(short type) {
1092        this.type=type;
1093    }
1094
1095    protected void addTag(String nameSpace, String nameSpaceSeperator,String name, String clazz){
1096        for(int i=0;i<tlds.length;i++) {
1097                if(tlds[i].getNameSpaceAndSeparator().equalsIgnoreCase(nameSpace+nameSpaceSeperator)){
1098                        TagLibTag tlt = new TagLibTag(tlds[i]);
1099                        tlt.setAttributeType(TagLibTag.ATTRIBUTE_TYPE_DYNAMIC);
1100                        tlt.setBodyContent("free");
1101                        tlt.setTagClass(clazz);
1102                        tlt.setName(name);
1103                        tlds[i].setTag(tlt              );
1104                }
1105        }
1106    }
1107    
1108    /**
1109     * set the optional directory of the tag library deskriptors
1110     * @param fileTld directory of the tag libray deskriptors
1111     * @throws TagLibException
1112     */
1113    protected void setTldFile(Resource fileTld) throws TagLibException {
1114        if(fileTld==null) return;
1115        this.tldFile=fileTld;
1116        String key;
1117        Map<String,TagLib> map=new HashMap<String,TagLib>();
1118        // First fill existing to set
1119        for(int i=0;i<tlds.length;i++) {
1120                key=getKey(tlds[i]);
1121                map.put(key,tlds[i]);
1122        }
1123        
1124        TagLib tl;
1125        
1126        // now overwrite with new data
1127        if(fileTld.isDirectory()) {
1128                Resource[] files=fileTld.listResources(new ExtensionResourceFilter(new String[]{"tld","tldx"}));
1129            for(int i=0;i<files.length;i++) {
1130                try {
1131                        tl = TagLibFactory.loadFromFile(files[i]);
1132                        key=getKey(tl);
1133                        if(!map.containsKey(key))
1134                                map.put(key,tl);
1135                        else 
1136                                overwrite(map.get(key),tl);
1137                }
1138                catch(TagLibException tle) {
1139                    SystemOut.printDate(out,"can't load tld "+files[i]);
1140                    tle.printStackTrace(getErrWriter());
1141                }
1142                
1143            }
1144        }
1145        else if(fileTld.isFile()){
1146                tl = TagLibFactory.loadFromFile(fileTld);
1147                key=getKey(tl);
1148                if(!map.containsKey(key))
1149                        map.put(key,tl);
1150                else overwrite(map.get(key),tl);
1151        }
1152
1153        // now fill back to array
1154        tlds=new TagLib[map.size()];
1155        int index=0;
1156        Iterator<TagLib> it = map.values().iterator();
1157        while(it.hasNext()) {
1158                tlds[index++]=it.next();
1159        }
1160    }
1161    
1162    public TagLib getCoreTagLib(){
1163        for(int i=0;i<tlds.length;i++) {
1164                if(tlds[i].getNameSpaceAndSeparator().equals("cf"))return tlds[i];      
1165        }
1166        throw new RuntimeException("no core taglib found"); // this should never happen
1167    }
1168    
1169    protected void setTagDirectory(Resource tagDirectory) {
1170        this.tagDirectory=tagDirectory;
1171        
1172        this.tagMapping= new MappingImpl(this,"/mapping-tag/",tagDirectory.getAbsolutePath(),null,ConfigImpl.INSPECT_NEVER,true,true,true,true,false,true,null);
1173        
1174        TagLib tl=getCoreTagLib();
1175        
1176        // now overwrite with new data
1177        if(tagDirectory.isDirectory()) {
1178                String[] files=tagDirectory.list(new ExtensionResourceFilter(new String[]{"cfm","cfc"}));
1179            for(int i=0;i<files.length;i++) {
1180                if(tl!=null)createTag(tl, files[i]);
1181                    
1182            }
1183        }
1184        
1185    }
1186    
1187    public void createTag(TagLib tl,String filename) {// Jira 1298
1188        String name=toName(filename);//filename.substring(0,filename.length()-(getCFCExtension().length()+1));
1189        
1190        TagLibTag tlt = new TagLibTag(tl);
1191        tlt.setName(name);
1192        tlt.setTagClass("lucee.runtime.tag.CFTagCore");
1193        tlt.setHandleExceptions(true);
1194        tlt.setBodyContent("free");
1195        tlt.setParseBody(false);
1196        tlt.setDescription("");
1197        tlt.setAttributeType(TagLibTag.ATTRIBUTE_TYPE_MIXED);
1198
1199
1200        TagLibTagAttr tlta = new TagLibTagAttr(tlt);
1201        tlta.setName("__filename");
1202        tlta.setRequired(true);
1203        tlta.setRtexpr(true);
1204        tlta.setType("string");
1205        tlta.setHidden(true);
1206        tlta.setDefaultValue(filename);
1207        tlt.setAttribute(tlta);
1208        
1209        tlta = new TagLibTagAttr(tlt);
1210        tlta.setName("__name");
1211        tlta.setRequired(true);
1212        tlta.setRtexpr(true);
1213        tlta.setHidden(true);
1214        tlta.setType("string");
1215        tlta.setDefaultValue(name);
1216        tlt.setAttribute(tlta);
1217        
1218        tlta = new TagLibTagAttr(tlt);
1219        tlta.setName("__isweb");
1220        tlta.setRequired(true);
1221        tlta.setRtexpr(true);
1222        tlta.setHidden(true);
1223        tlta.setType("boolean");
1224        tlta.setDefaultValue(this instanceof ConfigWeb?"true":"false");
1225        tlt.setAttribute(tlta);
1226        
1227        tl.setTag(tlt);
1228    }
1229    
1230    protected void setFunctionDirectory(Resource functionDirectory) {
1231        //this.functionDirectory=functionDirectory;
1232        this.functionMapping= new MappingImpl(this,"/mapping-function/",functionDirectory.getAbsolutePath(),null,ConfigImpl.INSPECT_NEVER,true,true,true,true,false,true,null);
1233        FunctionLib fl=flds[flds.length-1];
1234        
1235        // now overwrite with new data
1236        if(functionDirectory.isDirectory()) {
1237                String[] files=functionDirectory.list(new ExtensionResourceFilter(getCFMLExtensions()));
1238                
1239            for(int i=0;i<files.length;i++) {
1240                if(fl!=null)createFunction(fl, files[i]);
1241                    
1242            }
1243        }
1244        
1245    }
1246    
1247    public void createFunction(FunctionLib fl,String filename) {
1248        String name=toName(filename);//filename.substring(0,filename.length()-(getCFMLExtensions().length()+1));
1249        FunctionLibFunction flf = new FunctionLibFunction(fl);
1250        flf.setArgType(FunctionLibFunction.ARG_DYNAMIC);
1251        flf.setCls("lucee.runtime.functions.system.CFFunction");
1252        flf.setName(name);
1253        flf.setReturn("object");
1254        FunctionLibFunctionArg arg = new FunctionLibFunctionArg(flf);
1255        arg.setName("__filename");
1256        arg.setRequired(true);
1257        arg.setType("string");
1258        arg.setHidden(true);
1259        arg.setDefaultValue(filename);
1260        flf.setArg(arg);
1261        
1262        arg = new FunctionLibFunctionArg(flf);
1263        arg.setName("__name");
1264        arg.setRequired(true);
1265        arg.setHidden(true);
1266        arg.setType("string");
1267        arg.setDefaultValue(name);
1268        flf.setArg(arg);
1269        
1270        arg = new FunctionLibFunctionArg(flf);
1271        arg.setName("__isweb");
1272        arg.setRequired(true);
1273        arg.setHidden(true);
1274        arg.setType("boolean");
1275        arg.setDefaultValue(this instanceof ConfigWeb?"true":"false");
1276        flf.setArg(arg);
1277        
1278        
1279        
1280        fl.setFunction(flf);
1281    }
1282
1283    private static String toName(String filename) {
1284        int pos=filename.lastIndexOf('.');
1285        if(pos==-1)return filename;
1286        return filename.substring(0,pos);
1287        }
1288    
1289
1290        private void overwrite(TagLib existingTL, TagLib newTL) {
1291                Iterator<TagLibTag> it = newTL.getTags().values().iterator();
1292                while(it.hasNext()){
1293                        existingTL.setTag(it.next());
1294                }
1295        }
1296
1297        private String getKey(TagLib tl) {
1298                return tl.getNameSpaceAndSeparator().toLowerCase();
1299        }
1300        
1301        protected void setFldFile(Resource fileFld) throws FunctionLibException {
1302                // merge all together (backward compatibility)
1303        if(flds.length>1)for(int i=1;i<flds.length;i++) {
1304                overwrite(flds[0], flds[i]);
1305        }
1306        flds=new FunctionLib[]{flds[0]};
1307        
1308                
1309                if(fileFld==null) return;
1310        this.fldFile=fileFld;
1311
1312        
1313        // overwrite with addional functions
1314        FunctionLib fl;
1315        if(fileFld.isDirectory()) {
1316            Resource[] files=fileFld.listResources(new ExtensionResourceFilter("fld"));
1317            for(int i=0;i<files.length;i++) {
1318                try {
1319                        fl = FunctionLibFactory.loadFromFile(files[i]);
1320                        overwrite(flds[0],fl);
1321                        
1322                }
1323                catch(FunctionLibException fle) {
1324                    SystemOut.printDate(out,"can't load fld "+files[i]);
1325                    fle.printStackTrace(getErrWriter());
1326                }   
1327            }
1328        }
1329        else {
1330                fl = FunctionLibFactory.loadFromFile(fileFld);
1331                overwrite(flds[0],fl);
1332        }
1333    }
1334
1335    private void overwrite(FunctionLib existingFL, FunctionLib newFL) {
1336                Iterator<FunctionLibFunction> it = newFL.getFunctions().values().iterator();
1337                while(it.hasNext()){
1338                        existingFL.setFunction(it.next());
1339                }
1340        }
1341
1342    private String getKey(FunctionLib functionLib) {
1343                return functionLib.getDisplayName().toLowerCase();
1344        }
1345
1346        /**
1347     * sets if it is allowed to implizit query call, call a query member witot define name of the query. 
1348     * @param _allowImplicidQueryCall is allowed
1349     */
1350    protected void setAllowImplicidQueryCall(boolean _allowImplicidQueryCall) {
1351        this._allowImplicidQueryCall=_allowImplicidQueryCall;
1352    }
1353
1354    /**
1355     * sets if url and form scope will be merged
1356     * @param _mergeFormAndURL merge yes or no
1357     */
1358    protected void setMergeFormAndURL(boolean _mergeFormAndURL) {
1359        this._mergeFormAndURL=_mergeFormAndURL;
1360    }
1361    
1362    /**
1363     * @param strApplicationTimeout The applicationTimeout to set.
1364     * @throws PageException
1365     */
1366    void setApplicationTimeout(String strApplicationTimeout) throws PageException {
1367        setApplicationTimeout(Caster.toTimespan(strApplicationTimeout));
1368    }
1369    
1370    /**
1371     * @param applicationTimeout The applicationTimeout to set.
1372     */
1373    protected void setApplicationTimeout(TimeSpan applicationTimeout) {
1374        this.applicationTimeout = applicationTimeout;
1375    }
1376    
1377    /**
1378     * @param strSessionTimeout The sessionTimeout to set.
1379     * @throws PageException
1380     */
1381    protected void setSessionTimeout(String strSessionTimeout) throws PageException {
1382        setSessionTimeout(Caster.toTimespan(strSessionTimeout));
1383    }
1384    
1385    /**
1386     * @param sessionTimeout The sessionTimeout to set.
1387     */
1388    protected void setSessionTimeout(TimeSpan sessionTimeout) {
1389        this.sessionTimeout = sessionTimeout;
1390    }
1391    
1392    protected void setClientTimeout(String strClientTimeout) throws PageException {
1393        setClientTimeout(Caster.toTimespan(strClientTimeout));
1394    }
1395    
1396    /**
1397     * @param clientTimeout The sessionTimeout to set.
1398     */
1399    protected void setClientTimeout(TimeSpan clientTimeout) {
1400        this.clientTimeout = clientTimeout;
1401    }
1402    
1403    /**
1404     * @param strRequestTimeout The requestTimeout to set.
1405     * @throws PageException
1406     */
1407    protected void setRequestTimeout(String strRequestTimeout) throws PageException {
1408        setRequestTimeout(Caster.toTimespan(strRequestTimeout));
1409    }
1410    
1411    /**
1412     * @param requestTimeout The requestTimeout to set.
1413     */
1414    protected void setRequestTimeout(TimeSpan requestTimeout) {
1415        this.requestTimeout = requestTimeout;
1416    }
1417    
1418    /**
1419     * @param clientCookies The clientCookies to set.
1420     */
1421    protected void setClientCookies(boolean clientCookies) {
1422        this.clientCookies = clientCookies;
1423    }
1424    
1425    /**
1426     * @param clientManagement The clientManagement to set.
1427     */
1428    protected void setClientManagement(boolean clientManagement) {
1429        this.clientManagement = clientManagement;
1430    }
1431    
1432    /**
1433     * @param domainCookies The domainCookies to set.
1434     */
1435    protected void setDomainCookies(boolean domainCookies) {
1436        this.domainCookies = domainCookies;
1437    }
1438    
1439    /**
1440     * @param sessionManagement The sessionManagement to set.
1441     */
1442    protected void setSessionManagement(boolean sessionManagement) {
1443        this.sessionManagement = sessionManagement;
1444    }
1445    
1446    /**
1447     * @param spoolEnable The spoolEnable to set.
1448     */
1449    protected void setMailSpoolEnable(boolean spoolEnable) {
1450        this.spoolEnable = spoolEnable;
1451    }
1452    
1453    /**
1454     * @param mailTimeout The mailTimeout to set.
1455     */
1456    protected void setMailTimeout(int mailTimeout) {
1457        this.mailTimeout = mailTimeout;
1458    }
1459    
1460    /**
1461     * @param psq (preserve single quote) 
1462     * sets if sql string inside a cfquery will be prederved for Single Quotes
1463     */
1464    protected void setPSQL(boolean psq) {
1465        this.psq=psq;
1466    }
1467    
1468    /**
1469     * set if lucee make debug output or not
1470     * @param _debug debug or not
1471     */
1472    protected void setDebug(int _debug) {
1473        this._debug=_debug;
1474    }  
1475    
1476    protected void setDebugLogOutput(int debugLogOutput) {
1477        this.debugLogOutput=debugLogOutput;
1478    }   
1479    
1480    /**
1481     * sets the temp directory
1482     * @param strTempDirectory temp directory
1483     * @throws ExpressionException
1484     */
1485    protected void setTempDirectory(String strTempDirectory, boolean flush) throws ExpressionException {
1486        setTempDirectory(resources.getResource(strTempDirectory),flush);
1487    }   
1488    
1489    /**
1490     * sets the temp directory
1491     * @param tempDirectory temp directory
1492     * @throws ExpressionException
1493     */
1494    protected void setTempDirectory(Resource tempDirectory, boolean flush) throws ExpressionException {
1495        if(!isDirectory(tempDirectory) || !tempDirectory.isWriteable()) {
1496                SystemOut.printDate(getErrWriter(), "temp directory ["+tempDirectory+"] is not writable or can not be created, using directory ["+SystemUtil.getTempDirectory()+"] instead");
1497                tempDirectory=SystemUtil.getTempDirectory();
1498                if(!tempDirectory.isWriteable()){
1499                        SystemOut.printDate(getErrWriter(), "temp directory ["+tempDirectory+"] is not writable");
1500                }
1501        }
1502        if(flush)ResourceUtil.removeChildrenEL(tempDirectory);// start with a empty temp directory
1503        this.tempDirectory=tempDirectory;
1504    }
1505
1506    /**
1507     * sets the Schedule Directory
1508     * @param scheduleDirectory sets the schedule Directory 
1509     * @param logger
1510     * @throws PageException
1511     */
1512    protected void setScheduler(CFMLEngine engine,Resource scheduleDirectory) throws PageException {
1513        if(scheduleDirectory==null) {
1514                if(this.scheduler==null) this.scheduler=new SchedulerImpl(engine,"<?xml version=\"1.0\"?>\n<schedule></schedule>",this);
1515                return;
1516        }
1517        
1518        
1519        if(!isDirectory(scheduleDirectory)) throw new ExpressionException("schedule task directory "+scheduleDirectory+" doesn't exist or is not a directory");
1520        try {
1521                if(this.scheduler==null)
1522                        this.scheduler=new SchedulerImpl(engine,this,scheduleDirectory,SystemUtil.getCharset().name());
1523        } 
1524        catch (Exception e) {
1525            throw Caster.toPageException(e);
1526        }
1527    }
1528    
1529    /**
1530     * @param spoolInterval The spoolInterval to set.
1531     */
1532    protected void setMailSpoolInterval(int spoolInterval) {
1533        this.spoolInterval = spoolInterval;
1534    }
1535    
1536    /**
1537     * sets the timezone
1538     * @param timeZone
1539     */
1540    protected void setTimeZone(TimeZone timeZone) {
1541        this.timeZone=timeZone;
1542    }
1543    
1544    /**
1545     * sets the time server
1546     * @param timeServer
1547     */
1548    protected void setTimeServer(String timeServer) {
1549        this.timeServer=timeServer;
1550    }
1551
1552    /**
1553     * sets the locale
1554     * @param strLocale
1555     */
1556    protected void setLocale(String strLocale) {
1557        if(strLocale==null) {
1558            this.locale=Locale.US;
1559        }
1560        else {
1561            try {
1562                this.locale=Caster.toLocale(strLocale);
1563                if(this.locale==null)this.locale=Locale.US;
1564            } catch (ExpressionException e) {
1565                this.locale=Locale.US;
1566            }
1567        }
1568    }
1569    
1570    /**
1571     * sets the locale
1572     * @param locale
1573     */
1574    protected void setLocale(Locale locale) {
1575        this.locale=locale;
1576    }
1577
1578    /**
1579     * @param mappings The mappings to set.
1580     */
1581    protected void setMappings(Mapping[] mappings) {
1582        Arrays.sort(mappings,new Comparator(){ 
1583            public int compare(Object left, Object right) { 
1584                Mapping r = ((Mapping)right);
1585                Mapping l = ((Mapping)left);
1586                int rtn=r.getVirtualLowerCaseWithSlash().length()-l.getVirtualLowerCaseWithSlash().length();
1587                if(rtn==0) return slashCount(r)-slashCount(l);
1588                return rtn; 
1589            }
1590
1591                        private int slashCount(Mapping l) {
1592                                String str=l.getVirtualLowerCaseWithSlash();
1593                                int count=0,lastIndex=-1;
1594                                while((lastIndex=str.indexOf('/', lastIndex))!=-1) {
1595                                        count++;
1596                                        lastIndex++;
1597                                }
1598                                return count;
1599                        } 
1600        }); 
1601        this.mappings = mappings;
1602    }
1603    
1604    /**
1605     * @param datasources The datasources to set
1606     */
1607    protected void setDataSources(Map<String,DataSource> datasources) {
1608        this.datasources=datasources;
1609    }
1610
1611    /**
1612     * @param customTagMappings The customTagMapping to set.
1613     */
1614    protected void setCustomTagMappings(Mapping[] customTagMappings) {
1615        this.customTagMappings = customTagMappings;
1616    }
1617
1618    @Override
1619    public Mapping[] getCustomTagMappings() {
1620        return customTagMappings;
1621    }
1622    
1623    /**
1624     * @param mailServers The mailsServers to set.
1625     */
1626    protected void setMailServers(Server[] mailServers) {
1627        this.mailServers = mailServers;
1628    }
1629    
1630    /**
1631     * is file a directory or not, touch if not exist
1632     * @param directory
1633     * @return true if existing directory or has created new one
1634     */
1635    protected boolean isDirectory(Resource directory) {
1636        if(directory.exists()) return directory.isDirectory();
1637        try {
1638                        directory.createDirectory(true);
1639                        return true;
1640                } catch (IOException e) {
1641                        e.printStackTrace(getErrWriter());
1642                }
1643        return false;
1644    }
1645
1646    @Override
1647    public long getLoadTime() {
1648        return loadTime;
1649    }
1650
1651    /**
1652     * @param loadTime The loadTime to set.
1653     */
1654    protected void setLoadTime(long loadTime) {
1655        this.loadTime = loadTime;
1656    }
1657
1658    /**
1659     * @return Returns the configLogger.
1660     * /
1661    public Log getConfigLogger() {
1662        return configLogger;
1663    }*/
1664
1665    @Override
1666    public CFXTagPool getCFXTagPool() throws SecurityException {
1667        return cfxTagPool;
1668    }
1669
1670    /**
1671     * @param cfxTagPool The customTagPool to set.
1672     */
1673    protected void setCFXTagPool(CFXTagPool cfxTagPool) {
1674        this.cfxTagPool = cfxTagPool;
1675    }
1676    /**
1677     * @param cfxTagPool The customTagPool to set.
1678     */
1679    protected void setCFXTagPool(Map cfxTagPool) {
1680        this.cfxTagPool = new CFXTagPoolImpl(cfxTagPool);
1681    }
1682
1683    @Override
1684    public String getBaseComponentTemplate() {
1685        return baseComponentTemplate;
1686    }
1687
1688    /**
1689     * @return pagesource of the base component
1690     */
1691    public PageSource getBaseComponentPageSource() {
1692        return getBaseComponentPageSource(ThreadLocalPageContext.get());
1693    }
1694
1695    public PageSource getBaseComponentPageSource(PageContext pc) {
1696        if(baseComponentPageSource==null) {
1697                baseComponentPageSource=PageSourceImpl.best(getPageSources(pc,null,getBaseComponentTemplate(),false,false,true));
1698                if(!baseComponentPageSource.exists()) {
1699                        String baseTemplate = getBaseComponentTemplate();
1700                        String mod = ContractPath.call(pc, getBaseComponentTemplate(), false);
1701                        if(!mod.equals(baseTemplate)) {
1702                                baseComponentPageSource=PageSourceImpl.best(getPageSources(pc,null,mod,false,false,true));
1703                        
1704                        }
1705                }
1706
1707        }
1708        return baseComponentPageSource;
1709    }
1710    
1711    /**
1712     * @param template The baseComponent template to set.
1713     */
1714    protected void setBaseComponentTemplate(String template) {
1715        this.baseComponentPageSource=null;
1716        this.baseComponentTemplate = template;
1717    }
1718
1719    protected void setRestList(boolean restList) {
1720        this.restList=restList;
1721    }
1722
1723    public boolean getRestList() {
1724        return restList;
1725    }
1726    
1727    /**
1728     * @param clientType
1729     */
1730    protected void setClientType(short clientType) {
1731        this.clientType=clientType;
1732    }
1733    
1734    /**
1735     * @param strClientType
1736     */
1737    protected void setClientType(String strClientType) {
1738        strClientType=strClientType.trim().toLowerCase();
1739        if(strClientType.equals("file"))clientType=Config.CLIENT_SCOPE_TYPE_FILE;
1740        else if(strClientType.equals("db"))clientType=Config.CLIENT_SCOPE_TYPE_DB;
1741        else if(strClientType.equals("database"))clientType=Config.CLIENT_SCOPE_TYPE_DB;
1742        else clientType=Config.CLIENT_SCOPE_TYPE_COOKIE;
1743    }
1744    
1745    @Override
1746    public short getClientType() {
1747        return this.clientType;
1748    }
1749    
1750    /**
1751     * @param searchEngine The searchEngine to set.
1752     */
1753    protected void setSearchEngine(SearchEngine searchEngine) {
1754        this.searchEngine = searchEngine;
1755    }
1756
1757    @Override
1758    public int getComponentDataMemberDefaultAccess() {
1759        return componentDataMemberDefaultAccess;
1760    }
1761    /**
1762     * @param componentDataMemberDefaultAccess The componentDataMemberDefaultAccess to set.
1763     */
1764    protected void setComponentDataMemberDefaultAccess(
1765            int componentDataMemberDefaultAccess) {
1766        this.componentDataMemberDefaultAccess = componentDataMemberDefaultAccess;
1767    }
1768
1769    
1770    @Override
1771    public String getTimeServer() {
1772        return timeServer;
1773    }
1774
1775    @Override
1776    public String getComponentDumpTemplate() {
1777        return componentDumpTemplate;
1778    }
1779    
1780    /**
1781     * @param template The componentDump template to set.
1782     */
1783    protected void setComponentDumpTemplate(String template) {
1784        this.componentDumpTemplate = template;
1785    }
1786
1787    public String getSecurityToken() {
1788        if(securityToken==null){
1789                try {
1790                        securityToken = Md5.getDigestAsString(getConfigDir().getAbsolutePath());
1791                        } 
1792                catch (IOException e) {
1793                                return null;
1794                        }
1795        }
1796        return securityToken;
1797        }
1798
1799    @Override
1800    public String getId() {
1801        if(id==null){
1802                id = getId(getSecurityKey(),getSecurityToken(),false,securityKey);
1803        }
1804        return id;
1805        }
1806
1807    public static String getId(String key, String token,boolean addMacAddress,String defaultValue) {
1808        
1809                try {
1810                        if(addMacAddress){// because this was new we could swutch to a new ecryption // FUTURE cold we get rid of the old one?
1811                                return Hash.sha256(key+";"+token+":"+SystemUtil.getMacAddress());
1812                        }
1813                        return Md5.getDigestAsString(key+token);
1814                } 
1815        catch (Throwable t) {
1816                ExceptionUtil.rethrowIfNecessary(t);
1817                        return defaultValue;
1818                }
1819        }
1820    
1821    public String getSecurityKey() {
1822        return securityKey;
1823    }
1824
1825    @Override
1826    public String getDebugTemplate() {
1827        throw new PageRuntimeException(new DeprecatedException("no longer supported, use instead getDebugEntry(ip, defaultValue)"));
1828    }
1829
1830        @Override
1831        public String getErrorTemplate(int statusCode) {
1832                return errorTemplates.get(Caster.toString(statusCode));
1833        }
1834
1835        /**
1836         * @param errorTemplate the errorTemplate to set
1837         */
1838        protected void setErrorTemplate(int statusCode,String errorTemplate) {
1839                this.errorTemplates.put(Caster.toString(statusCode), errorTemplate);
1840        }
1841
1842    @Override
1843    public short getSessionType() {
1844        return sessionType;
1845    }
1846    /**
1847     * @param sessionType The sessionType to set.
1848     */
1849    protected void setSessionType(short sessionType) {
1850        this.sessionType = sessionType;
1851    }
1852    /**
1853     * @param type The sessionType to set.
1854     */
1855    protected void setSessionType(String type) {
1856        type=type.toLowerCase().trim();
1857        if(type.startsWith("cfm")) setSessionType(SESSION_TYPE_CFML);
1858        else if(type.startsWith("j")) setSessionType(SESSION_TYPE_J2EE);
1859        else setSessionType(SESSION_TYPE_CFML);
1860    }
1861
1862    @Override
1863    public abstract String getUpdateType() ;
1864
1865    @Override
1866    public abstract URL getUpdateLocation();
1867
1868    @Override
1869    public Resource getDeployDirectory() {
1870        return deployDirectory;
1871    }
1872
1873    /**
1874     * set the deploy directory, directory where lucee deploy transalted cfml classes (java and class files)
1875     * @param strDeployDirectory deploy directory
1876     * @throws ExpressionException
1877     */
1878    protected void setDeployDirectory(String strDeployDirectory) throws ExpressionException {
1879        setDeployDirectory(resources.getResource(strDeployDirectory));
1880    }
1881    
1882    /**
1883     * set the deploy directory, directory where lucee deploy transalted cfml classes (java and class files)
1884     * @param deployDirectory deploy directory
1885     * @throws ExpressionException
1886     * @throws ExpressionException
1887     */
1888    protected void setDeployDirectory(Resource deployDirectory) throws ExpressionException {
1889        if(!isDirectory(deployDirectory)) {
1890            throw new ExpressionException("deploy directory "+deployDirectory+" doesn't exist or is not a directory");
1891        }
1892        this.deployDirectory=deployDirectory;
1893    }
1894
1895    @Override
1896    public abstract Resource getRootDirectory();
1897
1898    /**
1899     * sets the compileType value.
1900     * @param compileType The compileType to set.
1901     */
1902    protected void setCompileType(short compileType) {
1903        this.compileType = compileType;
1904    }
1905
1906    /** FUTHER
1907     * Returns the value of suppresswhitespace.
1908     * @return value suppresswhitespace
1909     */
1910    public boolean isSuppressWhitespace() {
1911        return suppresswhitespace;
1912    }
1913
1914    /** FUTHER
1915     * sets the suppresswhitespace value.
1916     * @param suppresswhitespace The suppresswhitespace to set.
1917     */
1918    protected void setSuppressWhitespace(boolean suppresswhitespace) {
1919        this.suppresswhitespace = suppresswhitespace;
1920    }
1921
1922    public boolean isSuppressContent() {
1923        return suppressContent;
1924    }
1925    
1926    protected void setSuppressContent(boolean suppressContent) {
1927        this.suppressContent = suppressContent;
1928    }
1929
1930        @Override
1931        public String getDefaultEncoding() {
1932                return webCharset.name();
1933        }
1934        
1935        @Override
1936        public String getTemplateCharset() {
1937                return templateCharset.name();
1938        }
1939        public Charset _getTemplateCharset() {
1940                return templateCharset;
1941        }
1942        
1943        /**
1944         * sets the charset to read the files
1945         * @param templateCharset
1946         */
1947        protected void setTemplateCharset(String templateCharset) {
1948                this.templateCharset = CharsetUtil.toCharset(templateCharset, this.templateCharset);
1949        }
1950
1951        @Override
1952        public String getWebCharset() {
1953                return webCharset.name();
1954        }
1955        public Charset _getWebCharset() {
1956                return webCharset;
1957        }
1958        
1959        /**
1960         * sets the charset to read and write resources
1961         * @param resourceCharset
1962         */
1963        protected void setResourceCharset(String resourceCharset) {
1964                this.resourceCharset = CharsetUtil.toCharset(resourceCharset, this.resourceCharset);
1965        }
1966
1967        @Override
1968        public String getResourceCharset() {
1969                return resourceCharset.name();
1970        }
1971        public Charset _getResourceCharset() {
1972                return resourceCharset;
1973        }
1974        
1975        /**
1976         * sets the charset for the response stream
1977         * @param webCharset
1978         */
1979        protected void setWebCharset(String webCharset) {
1980                this.webCharset = CharsetUtil.toCharset(webCharset, this.webCharset);;
1981        }
1982
1983        public SecurityManager getSecurityManager() {
1984                return null;
1985        }
1986
1987        /**
1988         * @return the fldFile
1989         */
1990        public Resource getFldFile() {
1991                return fldFile;
1992        }
1993
1994        /**
1995         * @return the tldFile
1996         */
1997        public Resource getTldFile() {
1998                return tldFile;
1999        }
2000    
2001    @Override
2002        public DataSource[] getDataSources() {
2003                Map<String, DataSource> map = getDataSourcesAsMap();
2004                Iterator<DataSource> it = map.values().iterator();
2005                DataSource[] ds = new DataSource[map.size()];
2006                int count=0;
2007                
2008                while(it.hasNext()) {
2009                        ds[count++]=it.next();
2010                }
2011                return ds;
2012        }
2013        
2014        public Map<String,DataSource> getDataSourcesAsMap() {
2015        Map<String,DataSource> map=new HashMap<String, DataSource>();
2016        Iterator<Entry<String, DataSource>> it = datasources.entrySet().iterator();
2017        Entry<String, DataSource> entry;
2018        while(it.hasNext()) {
2019            entry = it.next();
2020            if(!entry.getKey().equals(QOQ_DATASOURCE_NAME))
2021                map.put(entry.getKey(),entry.getValue());
2022        }        
2023        return map;
2024    }
2025
2026        /**
2027         * @return the mailDefaultCharset
2028         */
2029        public String getMailDefaultEncoding() {
2030                return mailDefaultEncoding;
2031        }
2032
2033        /**
2034         * @param mailDefaultEncoding the mailDefaultCharset to set
2035         */
2036        protected void setMailDefaultEncoding(String mailDefaultEncoding) {
2037                this.mailDefaultEncoding = mailDefaultEncoding;
2038        }
2039
2040        protected void setDefaultResourceProvider(String strDefaultProviderClass, Map arguments) throws ClassException {
2041                Object o=ClassUtil.loadInstance(strDefaultProviderClass);
2042                if(o instanceof ResourceProvider) {
2043                        ResourceProvider rp=(ResourceProvider) o;
2044                        rp.init(null,arguments);
2045                        setDefaultResourceProvider(rp);
2046                }
2047                else 
2048                        throw new ClassException("object ["+Caster.toClassName(o)+"] must implement the interface "+ResourceProvider.class.getName());
2049        }
2050
2051        protected void setDefaultResourceProvider(Class defaultProviderClass, Map arguments) throws ClassException {
2052                Object o=ClassUtil.loadInstance(defaultProviderClass);
2053                if(o instanceof ResourceProvider) {
2054                        ResourceProvider rp=(ResourceProvider) o;
2055                        rp.init(null,arguments);
2056                        setDefaultResourceProvider(rp);
2057                }
2058                else 
2059                        throw new ClassException("object ["+Caster.toClassName(o)+"] must implement the interface "+ResourceProvider.class.getName());
2060        }
2061
2062        /**
2063         * @param defaultResourceProvider the defaultResourceProvider to set
2064         */
2065        protected void setDefaultResourceProvider(ResourceProvider defaultResourceProvider) {
2066                resources.registerDefaultResourceProvider(defaultResourceProvider);
2067        }
2068
2069        /**
2070         * @return the defaultResourceProvider
2071         */
2072        public ResourceProvider getDefaultResourceProvider() {
2073                return resources.getDefaultResourceProvider();
2074        }
2075
2076        protected void addResourceProvider(String strProviderScheme, String strProviderClass, Map arguments) throws ClassException {
2077                // old buld in S3
2078                Object o=ClassUtil.loadInstance(strProviderClass);
2079                
2080                if(o instanceof ResourceProvider) {
2081                        ResourceProvider rp=(ResourceProvider) o;
2082                        rp.init(strProviderScheme,arguments);
2083                        addResourceProvider(rp);
2084                }
2085                else 
2086                        throw new ClassException("object ["+Caster.toClassName(o)+"] must implement the interface "+ResourceProvider.class.getName());
2087        }
2088
2089        protected void addResourceProvider(String strProviderScheme, Class providerClass, Map arguments) throws ClassException {
2090                Object o=ClassUtil.loadInstance(providerClass);
2091                
2092                if(o instanceof ResourceProvider) {
2093                        ResourceProvider rp=(ResourceProvider) o;
2094                        rp.init(strProviderScheme,arguments);
2095                        addResourceProvider(rp);
2096                }
2097                else 
2098                        throw new ClassException("object ["+Caster.toClassName(o)+"] must implement the interface "+ResourceProvider.class.getName());
2099        }
2100
2101        protected void addResourceProvider(ResourceProvider provider) {
2102                resources.registerResourceProvider(provider);
2103        }
2104        
2105
2106        public void clearResourceProviders() {
2107                resources.reset();
2108        }
2109
2110        /**
2111         * @return return the resource providers
2112         */
2113        public ResourceProvider[] getResourceProviders() {
2114                return resources.getResourceProviders();
2115        }
2116
2117        protected void setResourceProviders(ResourceProvider[] resourceProviders) {
2118                for(int i=0;i<resourceProviders.length;i++) {
2119                        resources.registerResourceProvider(resourceProviders[i]);
2120                }
2121        }
2122
2123
2124        @Override
2125        public Resource getResource(String path) {
2126                return resources.getResource(path);
2127        }
2128
2129        @Override
2130        public ApplicationListener getApplicationListener() {
2131                return applicationListener;
2132        }
2133
2134        /**
2135         * @param applicationListener the applicationListener to set
2136         */
2137        protected void setApplicationListener(ApplicationListener applicationListener) {
2138                this.applicationListener = applicationListener;
2139        }
2140
2141        /**
2142         * @return the exceptionLogger
2143         */
2144        public LogAndSource getExceptionLogger() {
2145                return new LegacyLogger( getLog("exception", true));
2146        //throw new RuntimeException(new DeprecatedException("this method is no longer supported, use instead getLog"));
2147        }
2148        
2149        /**
2150         * @return the scriptProtect
2151         */
2152        public int getScriptProtect() {
2153                return scriptProtect;
2154        }
2155
2156        /**
2157         * @param scriptProtect the scriptProtect to set
2158         */
2159        protected void setScriptProtect(int scriptProtect) {
2160                this.scriptProtect = scriptProtect;
2161        }
2162
2163        /**
2164         * @return the proxyPassword
2165         */
2166        public ProxyData getProxyData() {
2167                return proxy;
2168        }
2169
2170        /**
2171         * @param proxy the proxyPassword to set
2172         */
2173        protected void setProxyData(ProxyData proxy) {
2174                this.proxy = proxy;
2175        }
2176
2177        @Override
2178        public boolean isProxyEnableFor(String host) {
2179                return false;// TODO proxyEnable;
2180        }
2181
2182        /**
2183         * @return the triggerComponentDataMember
2184         */
2185        public boolean getTriggerComponentDataMember() {
2186                return triggerComponentDataMember;
2187        }
2188
2189        /**
2190         * @param triggerComponentDataMember the triggerComponentDataMember to set
2191         */
2192        protected void setTriggerComponentDataMember(boolean triggerComponentDataMember) {
2193                this.triggerComponentDataMember = triggerComponentDataMember;
2194        }
2195
2196        @Override
2197        public Resource getClientScopeDir() {
2198                if(clientScopeDir==null) clientScopeDir=getConfigDir().getRealResource("client-scope");
2199                return clientScopeDir;
2200        }
2201
2202        public Resource getSessionScopeDir() {
2203                if(sessionScopeDir==null) sessionScopeDir=getConfigDir().getRealResource("session-scope");
2204                return sessionScopeDir;
2205        }
2206
2207        @Override
2208        public long getClientScopeDirSize() {
2209                return clientScopeDirSize;
2210        }
2211        public long getSessionScopeDirSize() {
2212                return sessionScopeDirSize;
2213        }
2214
2215        /**
2216         * @param clientScopeDir the clientScopeDir to set
2217         */
2218        protected void setClientScopeDir(Resource clientScopeDir) {
2219                this.clientScopeDir = clientScopeDir;
2220        }
2221        
2222        protected void setSessionScopeDir(Resource sessionScopeDir) {
2223                this.sessionScopeDir = sessionScopeDir;
2224        }
2225
2226        /**
2227         * @param clientScopeDirSize the clientScopeDirSize to set
2228         */
2229        protected void setClientScopeDirSize(long clientScopeDirSize) {
2230                this.clientScopeDirSize = clientScopeDirSize;
2231        }
2232
2233        @Override
2234        public ClassLoader getRPCClassLoader(boolean reload) throws IOException {
2235                
2236                if(rpcClassLoader!=null && !reload) return rpcClassLoader;
2237        
2238                Resource dir = getDeployDirectory().getRealResource("RPC");
2239                if(!dir.exists())dir.createDirectory(true);
2240                rpcClassLoader = new PhysicalClassLoader(dir,getClassLoader());
2241                return rpcClassLoader;
2242        }
2243        
2244        public void resetRPCClassLoader() {
2245                rpcClassLoader=null;
2246        }
2247
2248        protected void setCacheDir(Resource cacheDir) {
2249                this.cacheDir=cacheDir;
2250        }
2251        
2252        public Resource getCacheDir() {
2253                return this.cacheDir;
2254        }
2255
2256        public long getCacheDirSize() {
2257                return cacheDirSize;
2258        }
2259
2260        protected void setCacheDirSize(long cacheDirSize) {
2261                this.cacheDirSize=cacheDirSize;
2262        }
2263        
2264
2265
2266        protected void setDumpWritersEntries(DumpWriterEntry[] dmpWriterEntries) {
2267                this.dmpWriterEntries=dmpWriterEntries;
2268        }
2269        
2270        public DumpWriterEntry[] getDumpWritersEntries() {
2271                return dmpWriterEntries;
2272        }
2273        
2274        @Override
2275        public DumpWriter getDefaultDumpWriter(int defaultType) {
2276                DumpWriterEntry[] entries = getDumpWritersEntries();
2277                if(entries!=null)for(int i=0;i<entries.length;i++){
2278                        if(entries[i].getDefaultType()==defaultType) {
2279                                return entries[i].getWriter();
2280                        }
2281                }
2282                return new HTMLDumpWriter();
2283        }
2284
2285        @Override
2286        public DumpWriter getDumpWriter(String name) throws DeprecatedException {
2287                throw new DeprecatedException("this method is no longer supported");
2288        }
2289        
2290        public DumpWriter getDumpWriter(String name,int defaultType) throws ExpressionException {
2291                if(StringUtil.isEmpty(name)) return getDefaultDumpWriter(defaultType);
2292                
2293                DumpWriterEntry[] entries = getDumpWritersEntries();
2294                for(int i=0;i<entries.length;i++){
2295                        if(entries[i].getName().equals(name)) {
2296                                return entries[i].getWriter();
2297                        }
2298                }
2299                
2300                // error
2301                StringBuilder sb=new StringBuilder(); 
2302                for(int i=0;i<entries.length;i++){
2303                        if(i>0)sb.append(", ");
2304                        sb.append(entries[i].getName());
2305                }
2306                throw new ExpressionException("invalid format definition ["+name+"], valid definitions are ["+sb+"]");
2307        }
2308        
2309        @Override
2310        public boolean useComponentShadow() {
2311                return useComponentShadow;
2312        }
2313
2314        public boolean useComponentPathCache() {
2315                return useComponentPathCache;
2316        }
2317        
2318        public boolean useCTPathCache() {
2319                return useCTPathCache;
2320        }
2321        
2322        public void flushComponentPathCache() {
2323                if(componentPathCache!=null)componentPathCache.clear();
2324        }
2325        
2326        public void flushCTPathCache() {
2327                if(ctPatchCache!=null)ctPatchCache.clear();
2328        }
2329        
2330
2331        protected void setUseCTPathCache(boolean useCTPathCache) {
2332                this.useCTPathCache = useCTPathCache;
2333        }
2334        protected void setUseComponentPathCache(boolean useComponentPathCache) {
2335                this.useComponentPathCache = useComponentPathCache;
2336        }
2337
2338        /**
2339         * @param useComponentShadow the useComponentShadow to set
2340         */
2341        protected void setUseComponentShadow(boolean useComponentShadow) {
2342                this.useComponentShadow = useComponentShadow;
2343        }
2344        
2345        @Override
2346        public DataSource getDataSource(String datasource) throws DatabaseException {
2347                DataSource ds=(datasource==null)?null:(DataSource) datasources.get(datasource.toLowerCase());
2348                if(ds!=null) return ds;
2349                
2350                
2351                // create error detail
2352                DatabaseException de = new DatabaseException("datasource ["+datasource+"] doesn't exist",null,null,null);
2353                de.setDetail(ExceptionUtil.createSoundexDetail(datasource,datasources.keySet().iterator(),"datasource names"));
2354                de.setAdditional(KeyConstants._Datasource,datasource);
2355                throw de;
2356        }
2357        
2358        @Override
2359        public DataSource getDataSource(String datasource, DataSource defaultValue) {
2360                DataSource ds=(datasource==null)?null:(DataSource) datasources.get(datasource.toLowerCase());
2361                if(ds!=null) return ds;
2362                return defaultValue;
2363        }
2364
2365        @Override
2366        public PrintWriter getErrWriter() {
2367                return err;
2368        }
2369
2370        /**
2371         * @param err the err to set
2372         */
2373        protected void setErr(PrintWriter err) {
2374                this.err = err;
2375        }
2376
2377        @Override
2378        public PrintWriter getOutWriter() {
2379                return out;
2380        }
2381
2382        /**
2383         * @param out the out to set
2384         */
2385        protected void setOut(PrintWriter out) {
2386                this.out = out;
2387        }
2388
2389        public DatasourceConnectionPool getDatasourceConnectionPool() {
2390                return pool;
2391        }
2392
2393
2394
2395        public boolean doLocalCustomTag() {
2396                return doLocalCustomTag;
2397        }       
2398        
2399        @Override
2400        public String[] getCustomTagExtensions() {
2401                return customTagExtensions;
2402        }
2403        
2404        protected void setCustomTagExtensions(String[] customTagExtensions) {
2405                this.customTagExtensions = customTagExtensions;
2406        }
2407        
2408        protected void setDoLocalCustomTag(boolean doLocalCustomTag) {
2409                this.doLocalCustomTag= doLocalCustomTag;
2410        }
2411        
2412
2413        public boolean doComponentDeepSearch() {
2414                return doComponentTagDeepSearch;
2415        }
2416        
2417        protected void setDoComponentDeepSearch(boolean doComponentTagDeepSearch) {
2418                this.doComponentTagDeepSearch = doComponentTagDeepSearch;
2419        }
2420        
2421        @Override
2422        public boolean doCustomTagDeepSearch() {
2423                return doCustomTagDeepSearch;
2424        }
2425        
2426
2427        /**
2428         * @param doCustomTagDeepSearch the doCustomTagDeepSearch to set
2429         */
2430        protected void setDoCustomTagDeepSearch(boolean doCustomTagDeepSearch) {
2431                this.doCustomTagDeepSearch = doCustomTagDeepSearch;
2432        }
2433
2434        protected void setVersion(double version) {
2435                this.version=version;
2436        }
2437
2438        protected double setVersion(Document doc) {
2439                Element luceeConfiguration = doc.getDocumentElement();
2440                String strVersion = luceeConfiguration.getAttribute("version");
2441                return this.version=Caster.toDoubleValue(strVersion, 1.0d);
2442        }
2443        
2444        
2445
2446        /**
2447         * @return the version
2448         */
2449        public double getVersion() {
2450                return version;
2451        }
2452        
2453
2454
2455        public boolean closeConnection() {
2456                return closeConnection;
2457        }
2458
2459        protected void setCloseConnection(boolean closeConnection) {
2460                this.closeConnection=closeConnection;
2461        }
2462
2463        public boolean contentLength() {
2464                return contentLength;
2465        }
2466        
2467
2468        public boolean allowCompression() {
2469                return allowCompression;
2470        }
2471        protected void setAllowCompression(boolean allowCompression) {
2472                this.allowCompression= allowCompression;
2473        }
2474
2475
2476        protected void setContentLength(boolean contentLength) {
2477                this.contentLength=contentLength;
2478        }
2479
2480        /**
2481         * @return the constants
2482         */
2483        public Struct getConstants() {
2484                return constants;
2485        }
2486
2487        /**
2488         * @param constants the constants to set
2489         */
2490        protected void setConstants(Struct constants) {
2491                this.constants = constants;
2492        }
2493
2494        /**
2495         * @return the showVersion
2496         */
2497        public boolean isShowVersion() {
2498                return showVersion;
2499        }
2500
2501        /**
2502         * @param showVersion the showVersion to set
2503         */
2504        protected void setShowVersion(boolean showVersion) {
2505                this.showVersion = showVersion;
2506        }
2507
2508        protected void setRemoteClients(RemoteClient[] remoteClients) {
2509                this.remoteClients=remoteClients;
2510        }
2511        
2512        public RemoteClient[] getRemoteClients() {
2513                if(remoteClients==null) return new RemoteClient[0];
2514                return remoteClients;
2515        }
2516
2517        protected void setSecurityKey(String securityKey) {
2518                this.securityKey=securityKey;
2519                this.id=null;
2520        }
2521
2522        public SpoolerEngine getSpoolerEngine() {
2523                return remoteClientSpoolerEngine;
2524        }
2525
2526        protected void setRemoteClientDirectory(Resource remoteClientDirectory) {
2527                this.remoteClientDirectory=remoteClientDirectory;
2528        }
2529
2530        /**
2531         * @return the remoteClientDirectory
2532         */
2533        public Resource getRemoteClientDirectory() {
2534                return remoteClientDirectory;
2535        }
2536
2537        /**
2538         * @return the remoteClientLog
2539         */
2540        public LogAndSource getRemoteClientLog() {
2541                throw new RuntimeException(new DeprecatedException("this method is no longer supported, use instead getLog"));
2542        }
2543
2544        protected void setSpoolerEngine(SpoolerEngine spoolerEngine) {
2545                this.remoteClientSpoolerEngine=spoolerEngine;
2546        }
2547
2548        /**
2549         * @return the factory
2550         */
2551        public CFMLFactory getFactory() {
2552                return factory;
2553        }
2554
2555        /**
2556         * @return if error status code will be returned or not
2557         */
2558        public boolean getErrorStatusCode() {
2559                return errorStatusCode;
2560        }
2561
2562        /**
2563         * @param errorStatusCode the errorStatusCode to set
2564         */
2565        protected void setErrorStatusCode(boolean errorStatusCode) {
2566                this.errorStatusCode = errorStatusCode;
2567        }
2568
2569        @Override
2570        public int getLocalMode() {
2571                return localMode;
2572        }
2573
2574        /**
2575         * @param localMode the localMode to set
2576         */
2577        protected void setLocalMode(int localMode) {
2578                this.localMode = localMode;
2579        }
2580
2581        /**
2582         * @param strLocalMode the localMode to set
2583         */
2584        protected void setLocalMode(String strLocalMode) {
2585                this.localMode=AppListenerUtil.toLocalMode(strLocalMode,this.localMode);
2586        }
2587
2588        public Resource getVideoDirectory() {
2589                // TODO take from tag <video>
2590                Resource dir = getConfigDir().getRealResource("video");
2591            if(!dir.exists())dir.mkdirs();
2592            return dir;
2593        }
2594
2595
2596        public Resource getExtensionDirectory() {
2597                // TODO take from tag <extensions>
2598                Resource dir = getConfigDir().getRealResource("extensions");
2599            if(!dir.exists())dir.mkdirs();
2600            return dir;
2601        }
2602        
2603        protected void setExtensionProviders(ExtensionProvider[] extensionProviders) {
2604                this.extensionProviders=extensionProviders;
2605        }
2606
2607        public ExtensionProvider[] getExtensionProviders() {
2608                return extensionProviders;
2609        }
2610
2611        public Extension[] getExtensions() {
2612                return extensions;
2613        }
2614
2615        protected void setExtensions(Extension[] extensions) {
2616                
2617                this.extensions=extensions;
2618        }
2619
2620        protected void setExtensionEnabled(boolean extensionEnabled) {
2621                this.extensionEnabled=extensionEnabled;
2622        }
2623        public boolean isExtensionEnabled() {
2624                return extensionEnabled;
2625        }
2626
2627        @Override
2628        public boolean allowRealPath() {
2629                return allowRelPath;
2630        }
2631
2632        protected void setAllowRealPath(boolean allowRelPath) {
2633                this.allowRelPath=allowRelPath;
2634        }
2635
2636        /**
2637         * @return the classClusterScope
2638         */
2639        public Class getClusterClass() {
2640                return clusterClass;
2641        }
2642
2643        /**
2644         * @param clusterClass the classClusterScope to set
2645         */
2646        protected void setClusterClass(Class clusterClass) {
2647                this.clusterClass = clusterClass;
2648        }
2649
2650        @Override
2651        public Struct getRemoteClientUsage() {
2652                if(remoteClientUsage==null)remoteClientUsage=new StructImpl();
2653                return remoteClientUsage;
2654        }
2655        
2656        protected void setRemoteClientUsage(Struct remoteClientUsage) {
2657                this.remoteClientUsage=remoteClientUsage;
2658        }
2659
2660        @Override
2661        public Class getAdminSyncClass() {
2662                return adminSyncClass;
2663        }
2664
2665        protected void setAdminSyncClass(Class adminSyncClass) {
2666                this.adminSyncClass=adminSyncClass;
2667                this.adminSync=null;
2668        }
2669
2670        public AdminSync getAdminSync() throws ClassException {
2671                if(adminSync==null){
2672                        adminSync=(AdminSync) ClassUtil.loadInstance(getAdminSyncClass());
2673                        
2674                }
2675                return this.adminSync;
2676        }
2677        
2678        @Override
2679        public Class getVideoExecuterClass() {
2680                return videoExecuterClass;
2681        }
2682        
2683        protected void setVideoExecuterClass(Class videoExecuterClass) {
2684                this.videoExecuterClass=videoExecuterClass;
2685        }
2686
2687        protected void setUseTimeServer(boolean useTimeServer) {
2688                this.useTimeServer=useTimeServer;
2689        }
2690        
2691        public boolean getUseTimeServer() {
2692                return useTimeServer; 
2693        }
2694        
2695
2696        /**
2697         * @return the tagMappings
2698         */
2699        public Mapping getTagMapping() {
2700                return tagMapping;
2701        }
2702        
2703        public Mapping getFunctionMapping() {
2704                return functionMapping;
2705        }
2706
2707        /**
2708         * @return the tagDirectory
2709         */
2710        public Resource getTagDirectory() {
2711                return tagDirectory;
2712        }
2713
2714        public void setAMFCaster(String strCaster, Map args) {
2715
2716                amfCasterArguments=args;
2717        try{
2718                        if(StringUtil.isEmpty(strCaster) || "classic".equalsIgnoreCase(strCaster)) 
2719                        amfCasterClass=ClassicAMFCaster.class;
2720                else if("modern".equalsIgnoreCase(strCaster))
2721                        amfCasterClass=ModernAMFCaster.class;
2722                else {
2723                        Class caster = ClassUtil.loadClass(strCaster);
2724                        if((caster.newInstance() instanceof AMFCaster)) {
2725                                amfCasterClass=caster;
2726                        }
2727                        else {
2728                                amfCasterClass=ClassicAMFCaster.class;
2729                                throw new ClassException("object ["+Caster.toClassName(caster)+"] must implement the interface "+ResourceProvider.class.getName());
2730                        }
2731                }
2732        }
2733        catch(Exception e){
2734                e.printStackTrace();
2735        }
2736        }
2737        
2738        public void setAMFCaster(Class clazz, Map args) {
2739                amfCasterArguments=args;
2740        amfCasterClass=clazz;
2741        }
2742        
2743        public void setAMFConfigType(String strDeploy) {
2744                if(!StringUtil.isEmpty(strDeploy)){
2745                        if("xml".equalsIgnoreCase(strDeploy))amfConfigType=AMF_CONFIG_TYPE_XML;
2746                        else if("manual".equalsIgnoreCase(strDeploy))amfConfigType=AMF_CONFIG_TYPE_MANUAL;
2747                }
2748        }
2749        public void setAMFConfigType(int amfDeploy) {
2750                this.amfConfigType=amfDeploy;
2751        }
2752        public int getAMFConfigType() {
2753                return amfConfigType;
2754        }
2755
2756        public AMFCaster getAMFCaster(ConfigMap properties) throws ClassException {
2757                if(amfCaster==null){
2758                        if(properties!=null){
2759                                ConfigMap cases = properties.getPropertyAsMap("property-case", null);
2760                        if(cases!=null){
2761                                if(!amfCasterArguments.containsKey("force-cfc-lowercase"))
2762                                        amfCasterArguments.put("force-cfc-lowercase",Caster.toBoolean(cases.getPropertyAsBoolean("force-cfc-lowercase", false)));
2763                                if(!amfCasterArguments.containsKey("force-query-lowercase"))
2764                                        amfCasterArguments.put("force-query-lowercase",Caster.toBoolean(cases.getPropertyAsBoolean("force-query-lowercase", false)));
2765                                if(!amfCasterArguments.containsKey("force-struct-lowercase"))
2766                                        amfCasterArguments.put("force-struct-lowercase",Caster.toBoolean(cases.getPropertyAsBoolean("force-struct-lowercase", false)));
2767                                
2768                        }
2769                        ConfigMap access = properties.getPropertyAsMap("access", null);
2770                        if(access!=null){
2771                                if(!amfCasterArguments.containsKey("use-mappings"))
2772                                        amfCasterArguments.put("use-mappings",Caster.toBoolean(access.getPropertyAsBoolean("use-mappings", false)));
2773                                if(!amfCasterArguments.containsKey("method-access-level"))
2774                                        amfCasterArguments.put("method-access-level",access.getPropertyAsString("method-access-level","remote"));
2775                        }
2776                        }
2777                        
2778                        amfCaster=(AMFCaster)ClassUtil.loadInstance(amfCasterClass);
2779                        amfCaster.init(amfCasterArguments);
2780                }
2781                return amfCaster;
2782        }
2783        public Class getAMFCasterClass() {
2784                return amfCasterClass;
2785        }
2786        public Map getAMFCasterArguments() {
2787                if(amfCasterArguments==null) amfCasterArguments=new HashMap();
2788                return amfCasterArguments;
2789        }
2790
2791        public String getDefaultDataSource() {
2792                // TODO Auto-generated method stub
2793                return null;
2794        }
2795        protected void setDefaultDataSource(String defaultDataSource) {
2796                //this.defaultDataSource=defaultDataSource;
2797        }
2798
2799        /**
2800         * @return the inspectTemplate 
2801         */
2802        public short getInspectTemplate() {
2803                return inspectTemplate;
2804        }
2805        
2806
2807        public boolean getTypeChecking() {
2808                return typeChecking;
2809        }
2810        protected void setTypeChecking(boolean typeChecking) {
2811                this.typeChecking=typeChecking;
2812        }
2813        
2814
2815        /**
2816         * @param inspectTemplate the inspectTemplate to set
2817         */
2818        protected void setInspectTemplate(short inspectTemplate) {
2819                this.inspectTemplate = inspectTemplate;
2820        }
2821
2822        protected void setSerialNumber(String serial) {
2823                this.serial=serial;
2824        }
2825
2826        public String getSerialNumber() {
2827                return serial;
2828        }
2829
2830        protected void setCaches(Map<String,CacheConnection> caches) {
2831                this.caches=caches;
2832                Iterator<Entry<String, CacheConnection>> it = caches.entrySet().iterator();
2833                Entry<String, CacheConnection> entry;
2834                CacheConnection cc;
2835                while(it.hasNext()){
2836                        entry = it.next();
2837                        cc=entry.getValue();
2838                        if(cc.getName().equalsIgnoreCase(cacheDefaultConnectionNameTemplate)){
2839                                defaultCacheTemplate=cc;
2840                        }
2841                        else if(cc.getName().equalsIgnoreCase(cacheDefaultConnectionNameFunction)){
2842                                defaultCacheFunction=cc;
2843                        }
2844                        else if(cc.getName().equalsIgnoreCase(cacheDefaultConnectionNameQuery)){
2845                                defaultCacheQuery=cc;
2846                        }
2847                        else if(cc.getName().equalsIgnoreCase(cacheDefaultConnectionNameResource)){
2848                                defaultCacheResource=cc;
2849                        }
2850                        else if(cc.getName().equalsIgnoreCase(cacheDefaultConnectionNameObject)){
2851                                defaultCacheObject=cc;
2852                        }
2853                        else if(cc.getName().equalsIgnoreCase(cacheDefaultConnectionNameInclude)){
2854                                defaultCacheInclude=cc;
2855                        }
2856                }
2857        }
2858        
2859        @Override
2860        public Map<String,CacheConnection> getCacheConnections() {
2861                return caches;
2862        }
2863
2864        @Override
2865        public CacheConnection getCacheDefaultConnection(int type) {
2866                if(type==CACHE_DEFAULT_FUNCTION)        return defaultCacheFunction;
2867                if(type==CACHE_DEFAULT_OBJECT)          return defaultCacheObject;
2868                if(type==CACHE_DEFAULT_TEMPLATE)        return defaultCacheTemplate;
2869                if(type==CACHE_DEFAULT_QUERY)           return defaultCacheQuery;
2870                if(type==CACHE_DEFAULT_RESOURCE)        return defaultCacheResource;
2871                if(type==CACHE_DEFAULT_INCLUDE)         return defaultCacheInclude;
2872                return null;
2873        }
2874
2875        protected void setCacheDefaultConnectionName(int type,String cacheDefaultConnectionName) {
2876                if(type==CACHE_DEFAULT_FUNCTION)                cacheDefaultConnectionNameFunction=cacheDefaultConnectionName;
2877                else if(type==CACHE_DEFAULT_OBJECT)             cacheDefaultConnectionNameObject=cacheDefaultConnectionName;
2878                else if(type==CACHE_DEFAULT_TEMPLATE)   cacheDefaultConnectionNameTemplate=cacheDefaultConnectionName;
2879                else if(type==CACHE_DEFAULT_QUERY)              cacheDefaultConnectionNameQuery=cacheDefaultConnectionName;
2880                else if(type==CACHE_DEFAULT_RESOURCE)   cacheDefaultConnectionNameResource=cacheDefaultConnectionName;
2881                else if(type==CACHE_DEFAULT_INCLUDE)    cacheDefaultConnectionNameInclude=cacheDefaultConnectionName;
2882        }
2883        
2884        @Override
2885        public String getCacheDefaultConnectionName(int type) {
2886                if(type==CACHE_DEFAULT_FUNCTION)        return cacheDefaultConnectionNameFunction;
2887                if(type==CACHE_DEFAULT_OBJECT)          return cacheDefaultConnectionNameObject;
2888                if(type==CACHE_DEFAULT_TEMPLATE)        return cacheDefaultConnectionNameTemplate;
2889                if(type==CACHE_DEFAULT_QUERY)           return cacheDefaultConnectionNameQuery;
2890                if(type==CACHE_DEFAULT_RESOURCE)        return cacheDefaultConnectionNameResource;
2891                if(type==CACHE_DEFAULT_INCLUDE) return cacheDefaultConnectionNameInclude;
2892                return null;
2893        }
2894
2895        public String getCacheMD5() { 
2896                return cacheMD5;
2897        }
2898
2899        public void setCacheMD5(String cacheMD5) { 
2900                this.cacheMD5 = cacheMD5;
2901        }
2902
2903        public boolean getExecutionLogEnabled() {
2904                return executionLogEnabled;
2905        }
2906        protected void setExecutionLogEnabled(boolean executionLogEnabled) {
2907                this.executionLogEnabled= executionLogEnabled;
2908        }
2909
2910        public ExecutionLogFactory getExecutionLogFactory() {
2911                return executionLogFactory;
2912        }
2913        protected void setExecutionLogFactory(ExecutionLogFactory executionLogFactory) {
2914                this.executionLogFactory= executionLogFactory;
2915        }
2916        
2917        public ORMEngine resetORMEngine(PageContext pc, boolean force) throws PageException {
2918                //String name = pc.getApplicationContext().getName();
2919                //ormengines.remove(name);
2920                ORMEngine e = getORMEngine(pc);
2921                e.reload(pc,force);
2922                return e;
2923        }
2924        
2925        public ORMEngine getORMEngine(PageContext pc) throws PageException {
2926                String name = pc.getApplicationContext().getName();
2927                
2928                ORMEngine engine = ormengines.get(name);
2929                if(engine==null){
2930                        //try {
2931                        Throwable t=null;
2932                        
2933                        try {
2934                                engine=(ORMEngine)ClassUtil.loadInstance(ormEngineClass);
2935                                engine.init(pc);
2936                        }
2937                        catch (ClassException ce) {
2938                                t=ce;   
2939                        }
2940                        catch (NoClassDefFoundError ncfe) {
2941                                t=ncfe;
2942                        }
2943                        
2944                        if(t!=null) {
2945                                ApplicationException ae = new ApplicationException(
2946                                                        "cannot initialize ORM Engine ["+ormEngineClass.getName()+"], make sure you have added all the required jar files");
2947                                
2948                                ae.setStackTrace(t.getStackTrace());
2949                                ae.setDetail(t.getMessage());
2950                                
2951                                
2952                        
2953                        }
2954                                ormengines.put(name,engine);
2955                        /*}
2956                        catch (PageException pe) {
2957                                throw pe;
2958                        }*/
2959                }
2960                
2961                return engine; 
2962        }
2963        
2964        public Class<ORMEngine> getORMEngineClass() {
2965                return ormEngineClass; 
2966        }
2967        
2968        @Override
2969        public Mapping[] getComponentMappings() {
2970                return componentMappings;
2971        }
2972
2973        /**
2974         * @param componentMappings the componentMappings to set
2975         */
2976        protected void setComponentMappings(Mapping[] componentMappings) {
2977                this.componentMappings = componentMappings;
2978        }
2979        
2980        protected void setORMEngineClass(Class<ORMEngine> ormEngineClass) {
2981                this.ormEngineClass=ormEngineClass;
2982        }
2983
2984        protected void setORMConfig(ORMConfiguration ormConfig) {
2985                this.ormConfig=ormConfig;
2986        }
2987
2988        public ORMConfiguration getORMConfig() {
2989                return ormConfig;
2990        }
2991
2992
2993        private Map<String,PageSource> componentPathCache=null;//new ArrayList<Page>();
2994        private Map<String,InitFile> ctPatchCache=null;//new ArrayList<Page>();
2995        private Map<String,UDF> udfCache=new ReferenceMap();
2996
2997        
2998        public Page getCachedPage(PageContext pc,String pathWithCFC) throws PageException {
2999                if(componentPathCache==null) return null; 
3000                
3001                PageSource ps = componentPathCache.get(pathWithCFC.toLowerCase());
3002                if(ps==null) return null;
3003                return ((PageSourceImpl)ps).loadPage(pc,(Page)null);
3004        }
3005        
3006        public void putCachedPageSource(String pathWithCFC,PageSource ps) {
3007                if(componentPathCache==null) componentPathCache=Collections.synchronizedMap(new HashMap<String, PageSource>());//MUSTMUST new ReferenceMap(ReferenceMap.SOFT,ReferenceMap.SOFT); 
3008                componentPathCache.put(pathWithCFC.toLowerCase(),ps);
3009        }
3010        
3011        public InitFile getCTInitFile(PageContext pc,String key) {
3012                if(ctPatchCache==null) return null; 
3013                
3014                InitFile initFile = ctPatchCache.get(key.toLowerCase());
3015                if(initFile!=null){
3016                        if(MappingImpl.isOK(initFile.getPageSource()))return initFile;
3017                        ctPatchCache.remove(key.toLowerCase());
3018                }
3019                return null;
3020        }
3021        
3022        public void putCTInitFile(String key,InitFile initFile) {
3023                if(ctPatchCache==null) ctPatchCache=Collections.synchronizedMap(new HashMap<String, InitFile>());//MUSTMUST new ReferenceMap(ReferenceMap.SOFT,ReferenceMap.SOFT); 
3024                ctPatchCache.put(key.toLowerCase(),initFile);
3025        }
3026
3027        public Struct listCTCache() {
3028                Struct sct=new StructImpl();
3029                if(ctPatchCache==null) return sct; 
3030                Iterator<Entry<String, InitFile>> it = ctPatchCache.entrySet().iterator();
3031                
3032                Entry<String, InitFile> entry;
3033                while(it.hasNext()){
3034                        entry = it.next();
3035                        sct.setEL(entry.getKey(),entry.getValue().getPageSource().getDisplayPath());
3036                }
3037                return sct;
3038        }
3039        
3040        public void clearCTCache() {
3041                if(ctPatchCache==null) return; 
3042                ctPatchCache.clear();
3043        }
3044
3045        public void clearFunctionCache() {
3046                udfCache.clear();
3047        }
3048
3049        public UDF getFromFunctionCache(String key) {
3050                return udfCache.get(key);
3051        }
3052
3053        public void putToFunctionCache(String key,UDF udf) {
3054                udfCache.put(key, udf);
3055        }
3056        
3057        public Struct listComponentCache() {
3058                Struct sct=new StructImpl();
3059                if(componentPathCache==null) return sct; 
3060                Iterator<Entry<String, PageSource>> it = componentPathCache.entrySet().iterator();
3061                
3062                Entry<String, PageSource> entry;
3063                while(it.hasNext()){
3064                        entry = it.next();
3065                        sct.setEL(entry.getKey(),entry.getValue().getDisplayPath());
3066                }
3067                return sct;
3068        }
3069        
3070        public void clearComponentCache() {
3071                if(componentPathCache==null) return; 
3072                componentPathCache.clear();
3073        }
3074
3075        public ImportDefintion getComponentDefaultImport() {
3076                return componentDefaultImport;
3077        }
3078
3079        protected void setComponentDefaultImport(String str) {
3080                if(StringUtil.isEmpty(str)) return;
3081                if("org.railo.cfml.*".equalsIgnoreCase(str)) str="org.lucee.cfml.*";
3082                
3083                ImportDefintion cdi = ImportDefintionImpl.getInstance(str, null);
3084                if(cdi!=null)this.componentDefaultImport= cdi;
3085        }
3086
3087    /**
3088         * @return the componentLocalSearch
3089         */
3090        public boolean getComponentLocalSearch() {
3091                return componentLocalSearch;
3092        }
3093
3094        /**
3095         * @param componentLocalSearch the componentLocalSearch to set
3096         */
3097        protected void setComponentLocalSearch(boolean componentLocalSearch) {
3098                this.componentLocalSearch = componentLocalSearch;
3099        }
3100
3101    /**
3102         * @return the componentLocalSearch
3103         */
3104        public boolean getComponentRootSearch() {
3105                return componentRootSearch;
3106        }
3107
3108        /**
3109         * @param componentRootSearch the componentLocalSearch to set
3110         */
3111        protected void setComponentRootSearch(boolean componentRootSearch) {
3112                this.componentRootSearch = componentRootSearch;
3113        }
3114
3115        private final Map compressResources= new ReferenceMap(ReferenceMap.SOFT,ReferenceMap.SOFT);
3116
3117
3118        public Compress getCompressInstance(Resource zipFile, int format, boolean caseSensitive) {
3119                Compress compress=(Compress) compressResources.get(zipFile.getPath());
3120                if(compress==null) {
3121                        compress=new Compress(zipFile,format,caseSensitive);
3122                        compressResources.put(zipFile.getPath(), compress);
3123                }
3124                return compress;
3125        }
3126
3127        public boolean getSessionCluster() {
3128                return false;
3129        }
3130
3131        public boolean getClientCluster() {
3132                return false;
3133        }
3134        
3135        public String getClientStorage() {
3136                return clientStorage;
3137        }
3138        
3139        public String getSessionStorage() {
3140                return sessionStorage;
3141        }
3142        
3143        protected void setClientStorage(String clientStorage) {
3144                this.clientStorage = clientStorage;
3145        }
3146        
3147        protected void setSessionStorage(String sessionStorage) {
3148                this.sessionStorage = sessionStorage;
3149        }
3150        
3151        
3152        
3153        private Map<String,ComponentMetaData> componentMetaData=null;
3154        public ComponentMetaData getComponentMetadata(String key) {
3155                if(componentMetaData==null) return null;
3156                return componentMetaData.get(key.toLowerCase());
3157        }
3158
3159        public void putComponentMetadata(String key,ComponentMetaData data) {
3160                if(componentMetaData==null) componentMetaData=new HashMap<String, ComponentMetaData>();
3161                componentMetaData.put(key.toLowerCase(),data);
3162        }
3163        
3164        public void clearComponentMetadata() {
3165                if(componentMetaData==null) return; 
3166                componentMetaData.clear();
3167        }
3168        
3169        public static class ComponentMetaData {
3170
3171                public final Struct meta;
3172                public final long lastMod;
3173
3174                public ComponentMetaData(Struct meta, long lastMod) {
3175                        this.meta=meta;
3176                        this.lastMod=lastMod;
3177                }
3178        }
3179 
3180        private DebugEntry[] debugEntries;
3181        protected void setDebugEntries(DebugEntry[] debugEntries) {
3182                this.debugEntries=debugEntries;
3183        }
3184
3185        public DebugEntry[] getDebugEntries() {
3186                if(debugEntries==null)debugEntries=new DebugEntry[0];
3187                return debugEntries;
3188        }
3189        
3190        public DebugEntry getDebugEntry(String ip, DebugEntry defaultValue) {
3191                if(debugEntries.length==0) return defaultValue;
3192                short[] sarr;
3193
3194                try {
3195                        sarr = IPRange.toShortArray(ip);
3196                } catch (IOException e) {
3197                        return defaultValue;
3198                }
3199
3200                for(int i=0;i<debugEntries.length;i++){
3201                        if(debugEntries[i].getIpRange().inRange(sarr)) return debugEntries[i];
3202                }
3203                
3204                return defaultValue;
3205        }
3206
3207        private int debugMaxRecordsLogged=10;
3208        protected void setDebugMaxRecordsLogged(int debugMaxRecordsLogged) {
3209                this.debugMaxRecordsLogged=debugMaxRecordsLogged;
3210        }
3211
3212        public int getDebugMaxRecordsLogged() {
3213                return debugMaxRecordsLogged;
3214        }
3215
3216        private boolean dotNotationUpperCase=true;
3217        protected void setDotNotationUpperCase(boolean dotNotationUpperCase) {
3218                this.dotNotationUpperCase=dotNotationUpperCase;
3219        }
3220
3221        public boolean getDotNotationUpperCase() {
3222                return dotNotationUpperCase;
3223        }
3224
3225        private boolean defaultFunctionOutput=true;
3226        protected void setDefaultFunctionOutput(boolean defaultFunctionOutput) {
3227                this.defaultFunctionOutput=defaultFunctionOutput;
3228        }
3229
3230        public boolean getDefaultFunctionOutput() {
3231                return defaultFunctionOutput;
3232        }
3233
3234        private boolean getSuppressWSBeforeArg=true;
3235        protected void setSuppressWSBeforeArg(boolean getSuppressWSBeforeArg) {
3236                this.getSuppressWSBeforeArg=getSuppressWSBeforeArg;
3237        }
3238
3239        public boolean getSuppressWSBeforeArg() {
3240                return getSuppressWSBeforeArg;
3241        }
3242
3243        private RestSettings restSetting=new RestSettingImpl(false,UDF.RETURN_FORMAT_JSON);
3244        protected void setRestSetting(RestSettings restSetting){
3245                this.restSetting= restSetting;
3246        }
3247        
3248        @Override
3249        public RestSettings getRestSetting(){
3250                return restSetting; 
3251        }
3252
3253        protected void setMode(int mode) {
3254                this.mode=mode;
3255        }
3256
3257        public int getMode() {
3258                return mode;
3259        }
3260
3261        // do not move to Config interface, do instead getCFMLWriterClass
3262        protected void setCFMLWriterType(int writerType) {
3263                this.writerType=writerType;
3264        }
3265
3266        // do not move to Config interface, do instead setCFMLWriterClass
3267        public int getCFMLWriterType() {
3268                return writerType;
3269        }
3270
3271        private boolean bufferOutput=true;
3272
3273
3274        private int externalizeStringGTE=-1;
3275
3276
3277        private String salt;
3278
3279
3280
3281
3282        
3283
3284
3285
3286        public boolean getBufferOutput() {
3287                return bufferOutput;
3288        }
3289
3290        protected void setBufferOutput(boolean bufferOutput) {
3291                this.bufferOutput= bufferOutput;
3292        }
3293
3294        public int getDebugOptions() {
3295                return debugOptions;
3296        }
3297        
3298        public boolean hasDebugOptions(int debugOption) {
3299                return (debugOptions&debugOption)>0  ;
3300        }
3301        
3302        protected void setDebugOptions(int debugOptions) {
3303                this.debugOptions = debugOptions;
3304        }
3305
3306        protected void setCheckForChangesInConfigFile(boolean checkForChangesInConfigFile) {
3307                this.checkForChangesInConfigFile=checkForChangesInConfigFile;
3308        }
3309
3310        public boolean checkForChangesInConfigFile() {
3311                return checkForChangesInConfigFile;
3312        }
3313
3314
3315    public abstract int getLoginDelay();
3316
3317    public abstract boolean getLoginCaptcha();
3318    public abstract boolean getRememberMe();
3319
3320    public abstract boolean getFullNullSupport();
3321
3322    public abstract Cluster createClusterScope() throws PageException;
3323
3324        protected void setApiKey(String apiKey) {
3325                this.apiKey=apiKey;
3326        }
3327        
3328        public String getApiKey() {
3329                return apiKey;
3330        }
3331
3332        protected void setExternalizeStringGTE(int externalizeStringGTE) {
3333                this.externalizeStringGTE=externalizeStringGTE;
3334        }
3335        public int getExternalizeStringGTE() {
3336                return externalizeStringGTE;
3337        }
3338
3339        protected void addConsoleLayout(Layout layout) {
3340                consoleLayouts.add(layout);
3341                
3342        }
3343        protected void addResourceLayout(Layout layout) {
3344                resourceLayouts.add(layout);
3345        }
3346
3347        public Layout[] getConsoleLayouts() {
3348                if(consoleLayouts.isEmpty())
3349                        consoleLayouts.add(new PatternLayout("%d{dd.MM.yyyy HH:mm:ss,SSS} %-5p [%c] %m%n"));
3350                return consoleLayouts.toArray(new Layout[consoleLayouts.size()]);
3351                
3352        }
3353        public Layout[] getResourceLayouts() {
3354                if(resourceLayouts.isEmpty())
3355                        resourceLayouts.add(new ClassicLayout());
3356                return resourceLayouts.toArray(new Layout[resourceLayouts.size()]);
3357        }
3358
3359
3360        protected void clearLoggers() {
3361                if(loggers.size()==0) return;
3362                try{
3363                        Iterator<LoggerAndSourceData> it = loggers.values().iterator();
3364                        while(it.hasNext()){
3365                                it.next().close();
3366                        }
3367                }
3368                catch(Throwable t){
3369                ExceptionUtil.rethrowIfNecessary(t);
3370        }
3371                loggers.clear();
3372        }
3373        
3374        protected LoggerAndSourceData addLogger(String name, Level level,
3375                        String strAppender, Map<String, String> appenderArgs, 
3376                        String strLayout, Map<String, String> layoutArgs, boolean readOnly) {
3377                LoggerAndSourceData existing = loggers.get(name.toLowerCase());
3378                String id=LoggerAndSourceData.id(name.toLowerCase(), strAppender,appenderArgs,strLayout,layoutArgs,level,readOnly);
3379                
3380                if(existing!=null) {
3381                        if(existing.id().equals(id)) {
3382                                return existing;
3383                        }
3384                        existing.close();
3385                }
3386                
3387                
3388                LoggerAndSourceData las = new LoggerAndSourceData(this,id,name.toLowerCase(), strAppender,appenderArgs,strLayout,layoutArgs,level,readOnly);
3389                loggers.put(name.toLowerCase(),las);
3390                return las;
3391        }
3392        
3393        public Map<String,LoggerAndSourceData> getLoggers(){
3394                return loggers;
3395        }
3396        public Log getLog(String name){
3397                return getLog(name, true);
3398        }
3399        
3400        public Log getLog(String name, boolean createIfNecessary){
3401                LoggerAndSourceData lsd = getLoggerAndSourceData(name,createIfNecessary);
3402                if(lsd==null) return null;
3403                return lsd.getLog();
3404        }
3405        
3406        public Logger getLogger(String name, boolean createIfNecessary){
3407                LoggerAndSourceData lsd = getLoggerAndSourceData(name,createIfNecessary);
3408                if(lsd==null) return null;
3409                return ((LogAdapter)lsd.getLog()).getLogger();
3410        }
3411
3412        public LoggerAndSourceData getLoggerAndSourceData(String name, boolean createIfNecessary){
3413                LoggerAndSourceData las = loggers.get(name.toLowerCase());
3414                if(las==null) {
3415                        
3416                        if(!createIfNecessary) return null;
3417                        return addLogger(name, Level.ERROR, "console", null, "pattern", null,true);
3418                }
3419                return las;
3420        }
3421
3422        public Map<Key, Map<Key, Object>> getTagDefaultAttributeValues() {
3423                return tagDefaultAttributeValues==null?null:Duplicator.duplicateMap(tagDefaultAttributeValues,new HashMap<Key, Map<Key, Object>>(),true);
3424                
3425                /*Map<Key, Map<Key, Object>> map=new HashMap<Key, Map<Key, Object>>();
3426                Map<Key, Object> func=new HashMap<Key, Object>();
3427                Map<Key, Object> qry=new HashMap<Key, Object>();
3428                Map<Key, Object> inc=new HashMap<Key, Object>();
3429                map.put(KeyImpl.init("function"), func);
3430                map.put(KeyImpl.init("include"), inc);
3431                map.put(KeyImpl.init("query"), qry);
3432
3433                return  map;*/
3434        }
3435        
3436        protected void setTagDefaultAttributeValues(Map<Key, Map<Key, Object>> values) {
3437                this.tagDefaultAttributeValues=values;
3438        }
3439
3440        protected void setSalt(String salt) {
3441                this.salt=salt;
3442        }
3443
3444        public String getSalt() {
3445                return this.salt;
3446        }
3447
3448        public int getPasswordType() {
3449                if(password==null) return Password.HASHED_SALTED;// when there is no password, we will have a HS password
3450                return password.type;
3451        }
3452        public String getPasswordSalt() {
3453                if(password==null || password.salt==null) return this.salt;
3454                return password.salt;
3455        }
3456        
3457        public int getPasswordOrigin() {
3458                if(password==null) return Password.ORIGIN_UNKNOW;
3459                return password.origin;
3460        }
3461
3462        public int getQueueMax() {
3463                return queueMax;
3464        }
3465        protected void setQueueMax(int queueMax) {
3466                this.queueMax = queueMax;
3467        }
3468
3469        public long getQueueTimeout() {
3470                return queueTimeout;
3471        }
3472        protected void setQueueTimeout(long queueTimeout) {
3473                this.queueTimeout =  queueTimeout;
3474        }
3475
3476
3477        public boolean getQueueEnable() {
3478                return queueEnable;
3479        }
3480        protected void setQueueEnable(boolean queueEnable) {
3481                this.queueEnable =  queueEnable;
3482        }
3483
3484
3485        private boolean cgiScopeReadonly=true;
3486        public boolean getCGIScopeReadonly() {
3487                return cgiScopeReadonly;
3488        }
3489        protected void setCGIScopeReadonly(boolean cgiScopeReadonly) {
3490                this.cgiScopeReadonly = cgiScopeReadonly;
3491        }
3492
3493        public boolean allowCompiling() {
3494                return false;
3495        }
3496        
3497
3498        
3499}