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.listener;
020
021import java.nio.charset.Charset;
022import java.util.ArrayList;
023import java.util.HashMap;
024import java.util.Iterator;
025import java.util.List;
026import java.util.Locale;
027import java.util.Map;
028import java.util.Map.Entry;
029import java.util.TimeZone;
030
031import lucee.commons.date.TimeZoneUtil;
032import lucee.commons.io.CharsetUtil;
033import lucee.commons.io.res.Resource;
034import lucee.commons.lang.ExceptionUtil;
035import lucee.commons.lang.StringUtil;
036import lucee.commons.lang.types.RefBoolean;
037import lucee.runtime.Component;
038import lucee.runtime.ComponentPro;
039import lucee.runtime.ComponentSpecificAccess;
040import lucee.runtime.Mapping;
041import lucee.runtime.PageContext;
042import lucee.runtime.component.Member;
043import lucee.runtime.config.Config;
044import lucee.runtime.config.ConfigImpl;
045import lucee.runtime.config.ConfigWebUtil;
046import lucee.runtime.db.DataSource;
047import lucee.runtime.exp.DeprecatedException;
048import lucee.runtime.exp.PageException;
049import lucee.runtime.exp.PageRuntimeException;
050import lucee.runtime.i18n.LocaleFactory;
051import lucee.runtime.net.s3.Properties;
052import lucee.runtime.op.Caster;
053import lucee.runtime.op.Decision;
054import lucee.runtime.orm.ORMConfiguration;
055import lucee.runtime.orm.ORMConfigurationImpl;
056import lucee.runtime.rest.RestSettingImpl;
057import lucee.runtime.rest.RestSettings;
058import lucee.runtime.type.Array;
059import lucee.runtime.type.ArrayImpl;
060import lucee.runtime.type.Collection;
061import lucee.runtime.type.Collection.Key;
062import lucee.runtime.type.CustomType;
063import lucee.runtime.type.KeyImpl;
064import lucee.runtime.type.Struct;
065import lucee.runtime.type.StructImpl;
066import lucee.runtime.type.UDF;
067import lucee.runtime.type.UDFCustomType;
068import lucee.runtime.type.dt.TimeSpan;
069import lucee.runtime.type.scope.Scope;
070import lucee.runtime.type.util.KeyConstants;
071
072public class ModernApplicationContext extends ApplicationContextSupport {
073
074        private static final long serialVersionUID = -8230105685329758613L;
075
076        private static final Collection.Key APPLICATION_TIMEOUT = KeyConstants._applicationTimeout;
077        private static final Collection.Key CLIENT_MANAGEMENT = KeyConstants._clientManagement;
078        private static final Collection.Key CLIENT_STORAGE = KeyImpl.intern("clientStorage");
079        private static final Collection.Key SESSION_STORAGE = KeyImpl.intern("sessionStorage");
080        private static final Collection.Key LOGIN_STORAGE = KeyImpl.intern("loginStorage");
081        private static final Collection.Key SESSION_TYPE = KeyImpl.intern("sessionType");
082        private static final Collection.Key WS_SETTINGS = KeyImpl.intern("wssettings");
083        private static final Collection.Key TRIGGER_DATA_MEMBER = KeyImpl.intern("triggerDataMember");
084        private static final Collection.Key INVOKE_IMPLICIT_ACCESSOR = KeyImpl.intern("InvokeImplicitAccessor");
085        private static final Collection.Key SESSION_MANAGEMENT = KeyImpl.intern("sessionManagement");
086        private static final Collection.Key SESSION_TIMEOUT = KeyImpl.intern("sessionTimeout");
087        private static final Collection.Key CLIENT_TIMEOUT =  KeyImpl.intern("clientTimeout");
088        private static final Collection.Key REQUEST_TIMEOUT = KeyImpl.intern("requestTimeout");
089        private static final Collection.Key SET_CLIENT_COOKIES = KeyImpl.intern("setClientCookies");
090        private static final Collection.Key SET_DOMAIN_COOKIES = KeyImpl.intern("setDomainCookies");
091        private static final Collection.Key SCRIPT_PROTECT = KeyImpl.intern("scriptProtect");
092        private static final Collection.Key CUSTOM_TAG_PATHS = KeyImpl.intern("customtagpaths");
093        private static final Collection.Key COMPONENT_PATHS = KeyImpl.intern("componentpaths");
094        private static final Collection.Key SECURE_JSON_PREFIX = KeyImpl.intern("secureJsonPrefix");
095        private static final Collection.Key SECURE_JSON = KeyImpl.intern("secureJson");
096        private static final Collection.Key LOCAL_MODE = KeyImpl.intern("localMode");
097        private static final Collection.Key BUFFER_OUTPUT = KeyImpl.intern("bufferOutput");
098        private static final Collection.Key SESSION_CLUSTER = KeyImpl.intern("sessionCluster");
099        private static final Collection.Key CLIENT_CLUSTER = KeyImpl.intern("clientCluster");
100        
101
102        private static final Collection.Key DEFAULT_DATA_SOURCE = KeyImpl.intern("defaultdatasource");
103        private static final Collection.Key ORM_ENABLED = KeyImpl.intern("ormenabled");
104        private static final Collection.Key ORM_SETTINGS = KeyImpl.intern("ormsettings");
105        private static final Collection.Key IN_MEMORY_FILESYSTEM = KeyImpl.intern("inmemoryfilesystem");
106        private static final Collection.Key REST_SETTING = KeyImpl.intern("restsettings");
107        private static final Collection.Key JAVA_SETTING = KeyImpl.intern("javasettings");
108        private static final Collection.Key SCOPE_CASCADING = KeyImpl.intern("scopeCascading");
109        private static final Collection.Key TYPE_CHECKING = KeyImpl.intern("typeChecking");
110        
111        private static final Key SUPPRESS_CONTENT = KeyImpl.intern("suppressRemoteComponentContent");
112
113        private static final Key CGI_READONLY = KeyImpl.intern("CGIReadOnly");;
114
115
116        
117        
118        private ComponentPro component;
119        
120        private String name=null;
121        
122        private boolean setClientCookies;
123        private boolean setDomainCookies;
124        private boolean setSessionManagement;
125        private boolean setClientManagement;
126        private TimeSpan applicationTimeout;
127        private TimeSpan sessionTimeout;
128        private TimeSpan clientTimeout;
129        private TimeSpan requestTimeout;
130        private int loginStorage=Scope.SCOPE_COOKIE;
131        private int scriptProtect;
132        private boolean typeChecking;
133        private boolean allowCompression;
134        private Object defaultDataSource;
135        private boolean bufferOutput;
136        private boolean suppressContent;
137        private short sessionType;
138        private short wstype;
139        private boolean sessionCluster;
140        private boolean clientCluster;
141        private boolean cgiScopeReadonly;
142        
143
144        private String clientStorage;
145        private String sessionStorage;
146        private String secureJsonPrefix="//";
147        private boolean secureJson; 
148        private Mapping[] mappings;
149        private Mapping[] ctmappings;
150        private Mapping[] cmappings;
151        private DataSource[] dataSources;
152        
153        private Properties s3;
154        private boolean triggerComponentDataMember;
155        private Map<Integer,String> defaultCaches;
156        private boolean sameFormFieldAsArrays;
157        private boolean sameURLFieldAsArrays;
158        private Map<String,CustomType> customTypes;
159
160        private boolean initCustomTypes;
161        private boolean initApplicationTimeout;
162        private boolean initSessionTimeout;
163        private boolean initClientTimeout;
164        private boolean initRequestTimeout;
165        private boolean initSetClientCookies;
166        private boolean initSetClientManagement;
167        private boolean initSetDomainCookies;
168        private boolean initSetSessionManagement;
169        private boolean initScriptProtect;
170        private boolean initTypeChecking;
171        private boolean initAllowCompression;
172        private boolean initDefaultAttributeValues;
173        private boolean initClientStorage;
174        private boolean initSecureJsonPrefix;
175        private boolean initSecureJson;
176        private boolean initSessionStorage;
177        private boolean initSessionCluster;
178        private boolean initClientCluster;
179        private boolean initCGIScopeReadonly;
180        private boolean initLoginStorage;
181        private boolean initSessionType;
182        private boolean initWSType;
183        private boolean initTriggerComponentDataMember;
184        private boolean initMappings;
185        private boolean initDataSources;
186        private boolean initDefaultCaches;
187        //private boolean initSameFieldAsArrays;
188        private boolean initCTMappings;
189        private boolean initCMappings;
190        private int localMode;
191        private boolean initLocalMode;
192        private boolean initBufferOutput;
193        private boolean initSuppressContent;
194        private boolean initS3;
195        private boolean ormEnabled;
196        private ORMConfiguration ormConfig;
197        private boolean initRestSetting;
198        private RestSettings restSetting;
199        private boolean initJavaSettings;
200        private JavaSettings javaSettings;
201        private Object ormDatasource;
202        private Locale locale;
203        private boolean initLocale;
204        private TimeZone timeZone;
205        private boolean initTimeZone;
206        private Charset webCharset;
207        private boolean initWebCharset;
208        private Charset resourceCharset;
209        private boolean initResourceCharset;
210        
211        
212        
213        private Resource[] restCFCLocations;
214
215        private short scopeCascading=-1;
216
217                
218        public ModernApplicationContext(PageContext pc, ComponentPro cfc, RefBoolean throwsErrorWhileInit) {
219                super(pc.getConfig());
220                ConfigImpl ci = ((ConfigImpl)config);
221                setClientCookies=config.isClientCookies();
222                cgiScopeReadonly=ci.getCGIScopeReadonly();
223        
224        setDomainCookies=config.isDomainCookies();
225        setSessionManagement=config.isSessionManagement();
226        setClientManagement=config.isClientManagement();
227        sessionTimeout=config.getSessionTimeout();
228        clientTimeout=config.getClientTimeout();
229        requestTimeout=config.getRequestTimeout();
230        applicationTimeout=config.getApplicationTimeout();
231        scriptProtect=config.getScriptProtect();
232        typeChecking=ci.getTypeChecking();
233        allowCompression=ci.allowCompression();
234        this.defaultDataSource=config.getDefaultDataSource();
235        this.localMode=config.getLocalMode();
236        this.locale=config.getLocale();
237        this.timeZone=config.getTimeZone();
238        this.webCharset=ci._getWebCharset();
239        this.resourceCharset=((ConfigImpl)config)._getResourceCharset();
240        this.bufferOutput=ci.getBufferOutput();
241        suppressContent=ci.isSuppressContent();
242        this.sessionType=config.getSessionType();
243        this.wstype=WS_TYPE_AXIS1;
244        this.sessionCluster=config.getSessionCluster();
245        this.clientCluster=config.getClientCluster();
246        this.sessionStorage=ci.getSessionStorage();
247        this.clientStorage=ci.getClientStorage();
248        
249        this.triggerComponentDataMember=config.getTriggerComponentDataMember();
250        this.restSetting=config.getRestSetting();
251        this.javaSettings=new JavaSettingsImpl();
252        this.component=cfc;
253                
254        
255        // read scope cascading
256        initScopeCascading();
257        initSameFieldAsArray(pc);
258        
259                pc.addPageSource(component.getPageSource(), true);
260                try {
261                        
262                
263                        
264
265                        
266                        /////////// ORM /////////////////////////////////
267                        reinitORM(pc);
268                        
269                        
270                        throwsErrorWhileInit.setValue(false);
271                }
272                catch(Throwable t) {
273                        ExceptionUtil.rethrowIfNecessary(t);
274                        throwsErrorWhileInit.setValue(true);
275                        pc.removeLastPageSource(true);
276                }
277        }
278
279        public void initScopeCascading() {
280                Object o = get(component,SCOPE_CASCADING,null);
281                if(o!=null){
282                        scopeCascading=ConfigWebUtil.toScopeCascading(Caster.toString(o,null),(short)-1);
283                }
284        }
285        
286        
287        public short getScopeCascading() {
288                if(scopeCascading==-1) return config.getScopeCascadingType();
289                return scopeCascading;
290        }
291
292        @Override
293        public void setScopeCascading(short scopeCascading) {
294                this.scopeCascading= scopeCascading;
295        }
296
297        
298        public void reinitORM(PageContext pc) throws PageException {
299
300                // datasource
301                Object o = get(component,KeyConstants._datasource,null);
302                if(o!=null) {
303                        this.ormDatasource=this.defaultDataSource = AppListenerUtil.toDefaultDatasource(o);
304                }
305
306                // default datasource
307                o=get(component,DEFAULT_DATA_SOURCE,null);
308                if(o!=null) this.defaultDataSource =AppListenerUtil.toDefaultDatasource(o);
309                
310                // ormenabled
311                o = get(component,ORM_ENABLED,null);
312                if(o!=null && Caster.toBooleanValue(o,false)){
313                        this.ormEnabled=true;
314                        
315                        // settings
316                        o=get(component,ORM_SETTINGS,null);
317                        Struct settings;
318                        if(o instanceof Struct) settings=(Struct) o;
319                        else    settings=new StructImpl();
320                        AppListenerUtil.setORMConfiguration(pc, this, settings);
321                }
322        }
323
324        @Override
325        public boolean hasName() {
326                return true;//!StringUtil.isEmpty(getName());
327        }
328        
329        @Override
330        public String getName() {
331                if(this.name==null) {
332                        this.name=Caster.toString(get(component,KeyConstants._name,""),"");
333                }
334                return name;
335        }
336
337        @Override
338        public int getLoginStorage() {
339                if(!initLoginStorage) {
340                        String str=null;
341                        Object o = get(component,LOGIN_STORAGE,null);
342                        if(o!=null){ 
343                                str=Caster.toString(o,null);
344                                if(str!=null)loginStorage=AppListenerUtil.translateLoginStorage(str,loginStorage);
345                        }
346                        initLoginStorage=true; 
347                }
348                return loginStorage;
349        }
350
351        @Override
352        public TimeSpan getApplicationTimeout() {
353                if(!initApplicationTimeout) {
354                        Object o=get(component,APPLICATION_TIMEOUT,null);
355                        if(o!=null)applicationTimeout=Caster.toTimespan(o,applicationTimeout);
356                        initApplicationTimeout=true;
357                }
358                return applicationTimeout;
359        }
360
361        @Override
362        public TimeSpan getSessionTimeout() {
363                if(!initSessionTimeout) {
364                        Object o=get(component,SESSION_TIMEOUT,null);
365                        if(o!=null)sessionTimeout=Caster.toTimespan(o,sessionTimeout);
366                        initSessionTimeout=true;
367                }
368                return sessionTimeout;
369        }
370
371        @Override
372        public TimeSpan getClientTimeout() {
373                if(!initClientTimeout) {
374                        Object o=get(component,CLIENT_TIMEOUT,null);
375                        if(o!=null)clientTimeout=Caster.toTimespan(o,clientTimeout);
376                        initClientTimeout=true;
377                }
378                return clientTimeout;
379        }
380
381        @Override
382        public TimeSpan getRequestTimeout() {
383                if(!initRequestTimeout) {
384                        Object o=get(component,REQUEST_TIMEOUT,null);
385                        if(o==null)o=get(component,KeyConstants._timeout,null);
386                        if(o!=null)requestTimeout=Caster.toTimespan(o,requestTimeout);
387                        initRequestTimeout=true;
388                }
389                return requestTimeout;
390        }
391        
392        @Override
393        public void setRequestTimeout(TimeSpan requestTimeout) {
394                this.requestTimeout = requestTimeout;
395                initRequestTimeout=true;
396        }
397
398        @Override
399        public boolean isSetClientCookies() {
400                if(!initSetClientCookies) {
401                        Object o = get(component,SET_CLIENT_COOKIES,null);
402                        if(o!=null)setClientCookies=Caster.toBooleanValue(o,setClientCookies);
403                        initSetClientCookies=true;
404                }
405                return setClientCookies;
406        }
407
408        @Override
409        public boolean isSetClientManagement() {
410                if(!initSetClientManagement) {
411                        Object o = get(component,CLIENT_MANAGEMENT,null);
412                        if(o!=null)setClientManagement=Caster.toBooleanValue(o,setClientManagement);
413                        initSetClientManagement=true;
414                }
415                return setClientManagement;
416        }
417
418        @Override
419        public boolean isSetDomainCookies() {
420                if(!initSetDomainCookies) {
421                        Object o = get(component,SET_DOMAIN_COOKIES,null);
422                        if(o!=null)setDomainCookies=Caster.toBooleanValue(o,setDomainCookies);
423                        initSetDomainCookies=true;
424                }
425                return setDomainCookies;
426        }
427
428        @Override
429        public boolean isSetSessionManagement() {
430                if(!initSetSessionManagement) {
431                        Object o = get(component,SESSION_MANAGEMENT,null);
432                        if(o!=null)setSessionManagement=Caster.toBooleanValue(o,setSessionManagement);
433                        initSetSessionManagement=true; 
434                }
435                return setSessionManagement;
436        }
437
438        @Override
439        public String getClientstorage() {
440                if(!initClientStorage) {
441                        String str=Caster.toString(get(component,CLIENT_STORAGE,null),null);
442                        if(!StringUtil.isEmpty(str))clientStorage=str;
443                        initClientStorage=true;
444                }
445                return clientStorage;
446        }
447
448        @Override
449        public int getScriptProtect() {
450                if(!initScriptProtect) {
451                        String str=null;
452                        Object o = get(component,SCRIPT_PROTECT,null);
453                        if(o!=null){ 
454                                str=Caster.toString(o,null);
455                                if(str!=null)scriptProtect=AppListenerUtil.translateScriptProtect(str);
456                        }
457                        initScriptProtect=true; 
458                }
459                return scriptProtect;
460        }
461
462        @Override
463        public boolean getTypeChecking() {
464                if(!initTypeChecking) {
465                        Boolean b = Caster.toBoolean(get(component,TYPE_CHECKING,null),null);
466                        if(b!=null) typeChecking=b.booleanValue();
467                        initTypeChecking=true; 
468                }
469                return typeChecking;
470        }
471
472        @Override
473        public boolean getAllowCompression() {
474                if(!initAllowCompression) {
475                        Boolean b = Caster.toBoolean(get(component,KeyConstants._compression,null),null);
476                        if(b!=null) allowCompression=b.booleanValue();
477                        initAllowCompression=true; 
478                }
479                return allowCompression;
480        }
481
482        @Override
483        public void setAllowCompression(boolean allowCompression) {
484                this.allowCompression=allowCompression;
485                initAllowCompression=true;
486        }
487
488        @Override
489        public String getSecureJsonPrefix() {
490                if(!initSecureJsonPrefix) {
491                        Object o=get(component,SECURE_JSON_PREFIX,null);
492                        if(o!=null)secureJsonPrefix=Caster.toString(o,secureJsonPrefix);
493                        initSecureJsonPrefix=true;
494                }
495                return secureJsonPrefix;
496        }
497
498        @Override
499        public boolean getSecureJson() {
500                if(!initSecureJson) {
501                        Object o = get(component,SECURE_JSON,null);
502                        if(o!=null)secureJson=Caster.toBooleanValue(o,secureJson);
503                        initSecureJson=true; 
504                }
505                return secureJson;
506        }
507
508        @Override
509        public String getSessionstorage() {
510                if(!initSessionStorage) {
511                        String str=Caster.toString(get(component,SESSION_STORAGE,null),null);
512                        if(!StringUtil.isEmpty(str))sessionStorage=str;
513                        initSessionStorage=true;
514                }
515                return sessionStorage;
516        }
517
518        @Override
519        public boolean getSessionCluster() {
520                if(!initSessionCluster) {
521                        Object o = get(component,SESSION_CLUSTER,null);
522                        if(o!=null)sessionCluster=Caster.toBooleanValue(o,sessionCluster);
523                        initSessionCluster=true; 
524                }
525                return sessionCluster;
526        }
527
528        @Override
529        public boolean getClientCluster() {
530                if(!initClientCluster) {
531                        Object o = get(component,CLIENT_CLUSTER,null);
532                        if(o!=null)clientCluster=Caster.toBooleanValue(o,clientCluster);
533                        initClientCluster=true; 
534                }
535                return clientCluster;
536        }
537
538        @Override
539        public short getSessionType() {
540                if(!initSessionType) {
541                        String str=null;
542                        Object o = get(component,SESSION_TYPE,null);
543                        if(o!=null){ 
544                                str=Caster.toString(o,null);
545                                if(str!=null)sessionType=AppListenerUtil.toSessionType(str, sessionType);
546                        }
547                        initSessionType=true; 
548                }
549                return sessionType;
550        }
551        
552
553
554        @Override
555        public short getWSType() {
556                if(!initWSType) {
557                        String str=null;
558                        Object o = get(component,WS_SETTINGS,null);
559                        if(o instanceof Struct){ 
560                                Struct sct= (Struct) o;
561                                o=sct.get(KeyConstants._type,null);
562                                if(o instanceof String){ 
563                                        wstype=AppListenerUtil.toWSType(Caster.toString(o,null), WS_TYPE_AXIS1);
564                                }
565                        }
566                        initWSType=true; 
567                }
568                return wstype;
569        }
570
571        @Override
572        public void setWSType(short wstype) {
573                initWSType=true;
574                this.wstype=wstype;
575        }
576
577
578
579        @Override
580        public boolean getTriggerComponentDataMember() {
581                if(!initTriggerComponentDataMember) {
582                        Boolean b=null;
583                        Object o = get(component,INVOKE_IMPLICIT_ACCESSOR,null);
584                        if(o==null)o = get(component,TRIGGER_DATA_MEMBER,null);
585                        if(o!=null){ 
586                                b=Caster.toBoolean(o,null);
587                                if(b!=null)triggerComponentDataMember=b.booleanValue();
588                        }
589                        initTriggerComponentDataMember=true; 
590                }
591                return triggerComponentDataMember;
592        }
593
594
595
596        @Override
597        public void setTriggerComponentDataMember(boolean triggerComponentDataMember) {
598                initTriggerComponentDataMember=true;
599                this.triggerComponentDataMember=triggerComponentDataMember;
600        }
601        
602
603
604        @Override
605        public boolean getSameFieldAsArray(int scope) {
606                /*if(!initSameFieldAsArrays) {
607                        initSameFieldAsArray();
608                        initSameFieldAsArrays=true;
609                }*/
610                return Scope.SCOPE_URL==scope?sameURLFieldAsArrays:sameFormFieldAsArrays;
611        }
612        
613        public void initSameFieldAsArray(PageContext pc) {
614                boolean oldForm = pc.getApplicationContext().getSameFieldAsArray(Scope.SCOPE_FORM);
615                boolean oldURL=pc.getApplicationContext().getSameFieldAsArray(Scope.SCOPE_URL);
616                
617                // Form
618                Object o = get(component,KeyImpl.init("sameformfieldsasarray"),null);
619                if(o!=null && Decision.isBoolean(o))
620                        sameFormFieldAsArrays=Caster.toBooleanValue(o,false);
621                
622                // URL
623                o = get(component,KeyImpl.init("sameurlfieldsasarray"),null);
624                if(o!=null && Decision.isBoolean(o))
625                        sameURLFieldAsArrays=Caster.toBooleanValue(o,false);
626                
627                if(oldForm!=sameFormFieldAsArrays) ClassicApplicationContext.reinitScope(pc.formScope(),this) ;
628                if(oldURL!=sameURLFieldAsArrays) ClassicApplicationContext.reinitScope(pc.urlScope(),this) ;
629        }
630        
631
632        @Override
633        public String getDefaultCacheName(int type) {
634                if(!initDefaultCaches) {
635                        boolean hasResource=false;
636                        if(defaultCaches==null)defaultCaches=new HashMap<Integer, String>();
637                        Object o = get(component,KeyConstants._cache,null);
638                        if(o!=null && Decision.isStruct(o)){ 
639                                Struct sct = Caster.toStruct(o,null);
640                                if(sct!=null){
641                                        // Function
642                                        String name=Caster.toString(sct.get(KeyConstants._function,null),null);
643                                        if(!StringUtil.isEmpty(name,true)) defaultCaches.put(Config.CACHE_DEFAULT_FUNCTION, name.trim());
644                                        // Query
645                                        name=Caster.toString(sct.get(KeyConstants._query,null),null);
646                                        if(!StringUtil.isEmpty(name,true)) defaultCaches.put(Config.CACHE_DEFAULT_QUERY, name.trim());
647                                        // Template
648                                        name=Caster.toString(sct.get(KeyConstants._template,null),null);
649                                        if(!StringUtil.isEmpty(name,true)) defaultCaches.put(Config.CACHE_DEFAULT_TEMPLATE, name.trim());
650                                        // Object
651                                        name=Caster.toString(sct.get(KeyConstants._object,null),null);
652                                        if(!StringUtil.isEmpty(name,true)) defaultCaches.put(Config.CACHE_DEFAULT_OBJECT, name.trim());
653                                        // INCLUDE
654                                        name=Caster.toString(sct.get(KeyConstants._include,null),null);
655                                        if(!StringUtil.isEmpty(name,true)) defaultCaches.put(Config.CACHE_DEFAULT_INCLUDE, name.trim());
656                                        // Resource
657                                        name=Caster.toString(sct.get(KeyConstants._resource,null),null);
658                                        if(!StringUtil.isEmpty(name,true)) {
659                                                defaultCaches.put(Config.CACHE_DEFAULT_RESOURCE, name.trim());
660                                                hasResource=true;
661                                        }
662                                        
663                                }
664                        }
665                        
666                        // check alias inmemoryfilesystem 
667                        if(!hasResource) {
668                                String str = Caster.toString(get(component,IN_MEMORY_FILESYSTEM,null),null);
669                                if(!StringUtil.isEmpty(str,true)) {
670                                        defaultCaches.put(Config.CACHE_DEFAULT_RESOURCE, str.trim());
671                                }
672                                
673                        }
674                        
675                        
676                        
677                        initDefaultCaches=true; 
678                }
679                return defaultCaches.get(type);
680        }
681
682
683
684        @Override
685        public void setDefaultCacheName(int type, String cacheName) {
686                if(StringUtil.isEmpty(cacheName,true)) return;
687                
688                initDefaultCaches=true;
689                if(defaultCaches==null)defaultCaches=new HashMap<Integer, String>();
690                defaultCaches.put(type, cacheName.trim());
691        }
692        
693        
694        
695
696        @Override
697        public Mapping[] getMappings() {
698                if(!initMappings) {
699                        Object o = get(component,KeyConstants._mappings,null);
700                        if(o!=null)mappings=AppListenerUtil.toMappings(config,o,mappings,getSource());
701                        initMappings=true; 
702                }
703                return mappings;
704        }
705
706        @Override
707        public Mapping[] getCustomTagMappings() {
708                if(!initCTMappings) {
709                        Object o = get(component,CUSTOM_TAG_PATHS,null);
710                        if(o!=null)ctmappings=AppListenerUtil.toCustomTagMappings(config,o,getSource(),ctmappings);
711                        initCTMappings=true; 
712                }
713                return ctmappings;
714        }
715
716        @Override
717        public Mapping[] getComponentMappings() {
718                if(!initCMappings) {
719                        Object o = get(component,COMPONENT_PATHS,null);
720                        if(o!=null)cmappings=AppListenerUtil.toComponentMappings(config,o,getSource(),cmappings);
721                        initCMappings=true; 
722                }
723                return cmappings;
724        }
725
726        @Override
727        public int getLocalMode() {
728                if(!initLocalMode) {
729                        Object o = get(component,LOCAL_MODE,null);
730                        if(o!=null)localMode=AppListenerUtil.toLocalMode(o, localMode);
731                        initLocalMode=true; 
732                }
733                return localMode;
734        }
735        
736        
737
738        @Override
739        public Locale getLocale() {
740                if(!initLocale) {
741                        Object o = get(component,KeyConstants._locale,null);
742                        if(o!=null){
743                                String str = Caster.toString(o,null);
744                                if(!StringUtil.isEmpty(str))locale=LocaleFactory.getLocale(str,locale);
745                        }
746                        initLocale=true; 
747                }
748                return locale;
749        }
750
751        @Override
752        public TimeZone getTimeZone() {
753                if(!initTimeZone) {
754                        Object o = get(component,KeyConstants._timezone,null);
755                        if(o!=null){
756                                String str = Caster.toString(o,null);
757                                if(!StringUtil.isEmpty(str))timeZone=TimeZoneUtil.toTimeZone(str,timeZone);
758                        }
759                        initTimeZone=true; 
760                }
761                return timeZone;
762        }
763
764        @Override
765        public Charset getWebCharset() {
766                if(!initWebCharset)initCharset();
767                return webCharset;
768                
769        }
770        
771        @Override
772        public Charset getResourceCharset() {
773                if(!initResourceCharset)initCharset();
774                return resourceCharset;
775                
776        }
777        
778
779        private void initCharset() {
780                Object o = get(component,KeyConstants._charset,null);
781                if(o!=null){
782                        Struct sct = Caster.toStruct(o,null);
783                        if(sct!=null) {
784                                Charset web = CharsetUtil.toCharset(Caster.toString(sct.get(KeyConstants._web,null),null),null);
785                                if(!initWebCharset && web!=null) webCharset=web;
786                                Charset res = CharsetUtil.toCharset(Caster.toString(sct.get(KeyConstants._resource,null),null),null);
787                                if(!initResourceCharset && res!=null) resourceCharset=res;
788                        }
789                }
790                initWebCharset=true;
791                initResourceCharset=true; 
792        }
793
794
795
796        public boolean getBufferOutput() {
797                boolean bo = _getBufferOutput();
798                return bo;
799        }
800        
801        public boolean _getBufferOutput() {
802                if(!initBufferOutput) {
803                        Object o = get(component,BUFFER_OUTPUT,null);
804                        if(o!=null)bufferOutput=Caster.toBooleanValue(o, bufferOutput);
805                        initBufferOutput=true; 
806                }
807                return bufferOutput;
808        }
809        
810        public boolean getSuppressContent() {
811                if(!initSuppressContent) {
812                        Object o = get(component,SUPPRESS_CONTENT,null);
813                        if(o!=null)suppressContent=Caster.toBooleanValue(o, suppressContent);
814                        initSuppressContent=true; 
815                }
816                return suppressContent;
817        }
818        
819        public void setSuppressContent(boolean suppressContent) {
820                this.suppressContent=suppressContent;
821                initSuppressContent=true; 
822        }
823
824        @Override
825        public Properties getS3() {
826                if(!initS3) {
827                        Object o = get(component,KeyConstants._s3,null);
828                        if(o!=null && Decision.isStruct(o))s3=AppListenerUtil.toS3(Caster.toStruct(o,null));
829                        initS3=true; 
830                }
831                return s3;
832        }
833
834        @Override
835        public String getDefaultDataSource() {
836                throw new PageRuntimeException(new DeprecatedException("this method is no longer supported!"));
837        }
838        
839        @Override
840        public Object getDefDataSource() {
841                return defaultDataSource;
842        }
843
844        @Override
845        public DataSource[] getDataSources() {
846                if(!initDataSources) {
847                        Object o = get(component,KeyConstants._datasources,null);
848                        // if "this.datasources" does not exists, check if "this.datasource" exists and contains a struct
849                        /*if(o==null){
850                                o = get(component,KeyConstants._datasource,null);
851                                if(!Decision.isStruct(o)) o=null;
852                        }*/
853                        
854                        if(o!=null) dataSources=AppListenerUtil.toDataSources(o,dataSources);
855                        
856                        initDataSources=true; 
857                }
858                return dataSources;
859        }
860
861        @Override
862        public boolean isORMEnabled() {
863                return this.ormEnabled;
864        }
865
866        @Override
867        public String getORMDatasource() {
868                throw new PageRuntimeException(new DeprecatedException("this method is no longer supported!"));
869        }
870
871        @Override
872        public Object getORMDataSource() {
873                return ormDatasource;
874        }
875
876        @Override
877        public ORMConfiguration getORMConfiguration() {
878                return ormConfig;
879        }
880
881        public Component getComponent() {
882                return component;
883        }
884
885        public Object getCustom(Key key) {
886                try {
887                        ComponentSpecificAccess cw=ComponentSpecificAccess.toComponentSpecificAccess(Component.ACCESS_PRIVATE, component); 
888                        return cw.get(key,null);
889                } 
890                catch (Throwable t) {
891                        ExceptionUtil.rethrowIfNecessary(t);
892                }
893                
894                return null;
895        }
896        
897        
898        
899
900
901
902        private static Object get(ComponentPro app, Key name,String defaultValue) {
903                Member mem = app.getMember(Component.ACCESS_PRIVATE, name, true, false);
904                if(mem==null) return defaultValue;
905                return mem.getValue();
906        }
907
908        
909//////////////////////// SETTERS /////////////////////////
910        
911        
912        
913        @Override
914        public void setApplicationTimeout(TimeSpan applicationTimeout) {
915                initApplicationTimeout=true;
916                this.applicationTimeout=applicationTimeout;
917        }
918
919        @Override
920        public void setSessionTimeout(TimeSpan sessionTimeout) {
921                initSessionTimeout=true;
922                this.sessionTimeout=sessionTimeout;
923        }
924
925        @Override
926        public void setClientTimeout(TimeSpan clientTimeout) {
927                initClientTimeout=true;
928                this.clientTimeout=clientTimeout;
929        }
930
931        @Override
932        public void setClientstorage(String clientstorage) {
933                initClientStorage=true;
934                this.clientStorage=clientstorage;
935        }
936
937        @Override
938        public void setSessionstorage(String sessionstorage) {
939                initSessionStorage=true;
940                this.sessionStorage=sessionstorage;
941        }
942
943        @Override
944        public void setCustomTagMappings(Mapping[] customTagMappings) {
945                initCTMappings=true;
946                this.ctmappings=customTagMappings;
947        }
948
949        @Override
950        public void setComponentMappings(Mapping[] componentMappings) {
951                initCMappings=true;
952                this.cmappings=componentMappings;
953        }
954
955        @Override
956        public void setMappings(Mapping[] mappings) {
957                initMappings=true;
958                this.mappings=mappings;
959        }
960        public void setDataSources(DataSource[] dataSources) {
961                initDataSources=true;
962                this.dataSources=dataSources;
963        }
964
965        @Override
966        public void setLoginStorage(int loginStorage) {
967                initLoginStorage=true;
968                this.loginStorage=loginStorage;
969        }
970
971        @Override
972        public void setDefaultDataSource(String datasource) {
973                this.defaultDataSource=datasource;
974        }
975
976        @Override
977        public void setDefDataSource(Object datasource) {
978                this.defaultDataSource=datasource;
979        }
980
981        @Override
982        public void setScriptProtect(int scriptrotect) {
983                initScriptProtect=true;
984                this.scriptProtect=scriptrotect;
985        }
986
987
988        @Override
989        public void setTypeChecking(boolean typeChecking) {
990                initTypeChecking=true;
991                this.typeChecking=typeChecking;
992        }
993
994        @Override
995        public void setSecureJson(boolean secureJson) {
996                initSecureJson=true;
997                this.secureJson=secureJson;
998        }
999
1000        @Override
1001        public void setSecureJsonPrefix(String secureJsonPrefix) {
1002                initSecureJsonPrefix=true;
1003                this.secureJsonPrefix=secureJsonPrefix;
1004        }
1005
1006        @Override
1007        public void setSetClientCookies(boolean setClientCookies) {
1008                initSetClientCookies=true;
1009                this.setClientCookies=setClientCookies;
1010        }
1011
1012        @Override
1013        public void setSetClientManagement(boolean setClientManagement) {
1014                initSetClientManagement=true;
1015                this.setClientManagement=setClientManagement;
1016        }
1017
1018        @Override
1019        public void setSetDomainCookies(boolean setDomainCookies) {
1020                initSetDomainCookies=true;
1021                this.setDomainCookies=setDomainCookies;
1022        }
1023
1024        @Override
1025        public void setSetSessionManagement(boolean setSessionManagement) {
1026                initSetSessionManagement=true;
1027                this.setSessionManagement=setSessionManagement;
1028        }
1029
1030        @Override
1031        public void setLocalMode(int localMode) {
1032                initLocalMode=true;
1033                this.localMode=localMode;
1034        }
1035
1036        @Override
1037        public void setLocale(Locale locale) {
1038                initLocale=true;
1039                this.locale=locale;
1040        }
1041
1042        @Override
1043        public void setTimeZone(TimeZone timeZone) {
1044                initTimeZone=true;
1045                this.timeZone=timeZone;
1046        }
1047        
1048        public void setWebCharset(Charset webCharset) {
1049                initWebCharset=true;
1050                this.webCharset=webCharset;
1051        }
1052        
1053        public void setResourceCharset(Charset resourceCharset) {
1054                initResourceCharset=true;
1055                this.resourceCharset=resourceCharset;
1056        }
1057        
1058        
1059        
1060        public void setBufferOutput(boolean bufferOutput) {
1061                initBufferOutput=true;
1062                this.bufferOutput=bufferOutput;
1063        }
1064
1065        @Override
1066        public void setSessionType(short sessionType) {
1067                initSessionType=true;
1068                this.sessionType=sessionType;
1069        }
1070
1071        @Override
1072        public void setClientCluster(boolean clientCluster) {
1073                initClientCluster=true;
1074                this.clientCluster=clientCluster;
1075        }
1076
1077        @Override
1078        public void setSessionCluster(boolean sessionCluster) {
1079                initSessionCluster=true;
1080                this.sessionCluster=sessionCluster;
1081        }
1082
1083        @Override
1084        public void setS3(Properties s3) {
1085                initS3=true;
1086                this.s3=s3;
1087        }
1088
1089        @Override
1090        public void setORMEnabled(boolean ormEnabled) {
1091                this.ormEnabled=ormEnabled;
1092        }
1093
1094        @Override
1095        public void setORMConfiguration(ORMConfiguration ormConfig) {
1096                this.ormConfig=ormConfig;
1097        }
1098
1099        @Override
1100        public void setORMDatasource(String ormDatasource) {
1101                this.ormDatasource=ormDatasource;
1102        }
1103
1104        @Override
1105        public void setORMDataSource(Object ormDatasource) {
1106                this.ormDatasource=ormDatasource;
1107        }
1108
1109        @Override
1110        public Resource getSource() {
1111                return component.getPageSource().getResource();
1112        }
1113
1114
1115
1116        @Override
1117        public RestSettings getRestSettings() {
1118                initRest();
1119                return restSetting;
1120        }
1121
1122        @Override
1123        public Resource[] getRestCFCLocations() {
1124                initRest();
1125                return restCFCLocations;
1126        }
1127
1128        private void initRest() {
1129                if(!initRestSetting) {
1130                        Object o = get(component,REST_SETTING,null);
1131                        if(o!=null && Decision.isStruct(o)){
1132                                Struct sct = Caster.toStruct(o,null);
1133                                
1134                                // cfclocation
1135                                Object obj = sct.get(KeyConstants._cfcLocation,null);
1136                                if(obj==null) obj = sct.get(KeyConstants._cfcLocations,null);
1137                                List<Resource> list = ORMConfigurationImpl.loadCFCLocation(config, null, obj,true);
1138                                restCFCLocations=list==null?null:list.toArray(new Resource[list.size()]);
1139                                
1140                                // skipCFCWithError
1141                                boolean skipCFCWithError=Caster.toBooleanValue(sct.get(KeyConstants._skipCFCWithError,null),restSetting.getSkipCFCWithError());
1142                                
1143                                // returnFormat
1144                                int returnFormat=Caster.toIntValue(sct.get(KeyConstants._returnFormat,null),restSetting.getReturnFormat());
1145                                
1146                                restSetting=new RestSettingImpl(skipCFCWithError,returnFormat);
1147                                
1148                        }
1149                        initRestSetting=true; 
1150                }
1151        }
1152        
1153
1154        @Override
1155        public JavaSettings getJavaSettings() {
1156                initJava();
1157                return javaSettings;
1158        }
1159        
1160        private void initJava() {
1161                if(!initJavaSettings) {
1162                        Object o = get(component,JAVA_SETTING,null);
1163                        if(o!=null && Decision.isStruct(o)){
1164                                Struct sct = Caster.toStruct(o,null);
1165                                
1166                                // loadPaths
1167                                Object obj = sct.get(KeyImpl.init("loadPaths"),null);
1168                                List<Resource> paths;
1169                                if(obj!=null) {
1170                                        paths = ORMConfigurationImpl.loadCFCLocation(config, null, obj,false);  
1171                                }
1172                                else paths=new ArrayList<Resource>();
1173                                        
1174                                
1175                                // loadCFMLClassPath
1176                                Boolean loadCFMLClassPath=Caster.toBoolean(sct.get(KeyImpl.init("loadCFMLClassPath"),null),null);
1177                                if(loadCFMLClassPath==null)
1178                                        loadCFMLClassPath=Caster.toBoolean(sct.get(KeyImpl.init("loadColdFusionClassPath"),null),null);
1179                                if(loadCFMLClassPath==null)loadCFMLClassPath=javaSettings.loadCFMLClassPath();
1180                                        
1181                                // reloadOnChange
1182                                boolean reloadOnChange=Caster.toBooleanValue(sct.get(KeyImpl.init("reloadOnChange"),null),javaSettings.reloadOnChange());
1183                                
1184                                // watchInterval
1185                                int watchInterval=Caster.toIntValue(sct.get(KeyImpl.init("watchInterval"),null),javaSettings.watchInterval());
1186                                
1187                                // watchExtensions
1188                                obj = sct.get(KeyImpl.init("watchExtensions"),null);
1189                                List<String> extensions=new ArrayList<String>();
1190                                if(obj!=null) {
1191                                        Array arr;
1192                                        if(Decision.isArray(obj)) {
1193                                                try {
1194                                                        arr = Caster.toArray(obj);
1195                                                } catch (PageException e) {
1196                                                        arr=new ArrayImpl();
1197                                                }
1198                                        }
1199                                        else {
1200                                                arr=lucee.runtime.type.util.ListUtil.listToArrayRemoveEmpty(Caster.toString(obj,""), ',');
1201                                        }
1202                                        Iterator<Object> it = arr.valueIterator();
1203                                        String ext;
1204                                        while(it.hasNext()){
1205                                                ext=Caster.toString(it.next(),null);
1206                                                if(StringUtil.isEmpty(ext))continue;
1207                                                ext=ext.trim();
1208                                                if(ext.startsWith("."))ext=ext.substring(1);
1209                                                if(ext.startsWith("*."))ext=ext.substring(2);
1210                                                extensions.add(ext);
1211                                        }
1212                                        
1213                                }
1214                                javaSettings=new JavaSettingsImpl(
1215                                                paths.toArray(new Resource[paths.size()]),
1216                                                loadCFMLClassPath,reloadOnChange,watchInterval,
1217                                                extensions.toArray(new String[extensions.size()]));
1218                                
1219                        }
1220                        initJavaSettings=true; 
1221                }
1222        }
1223
1224        @Override
1225        public Map<Collection.Key, Object> getTagAttributeDefaultValues(String tagClassName) {
1226                if(!initDefaultAttributeValues) {
1227                        // this.tag.<tagname>.<attribute-name>=<value>
1228                        Struct sct = Caster.toStruct(get(component,KeyConstants._tag,null),null);
1229                        if(sct!=null) {
1230                                setTagAttributeDefaultValues(sct);
1231                        }
1232                }
1233                return super.getTagAttributeDefaultValues(tagClassName);
1234        }
1235        
1236        @Override
1237        public void setTagAttributeDefaultValues(Struct sct) {
1238                initDefaultAttributeValues=true;
1239                super.setTagAttributeDefaultValues(sct);
1240        }
1241
1242        @Override
1243        public CustomType getCustomType(String strType) {
1244                if(!initCustomTypes) {
1245                        if(customTypes==null)
1246                                customTypes=new HashMap<String, CustomType>();
1247                        
1248                        // this.type.susi=function(any value){};
1249                        Struct sct = Caster.toStruct(get(component,KeyConstants._type,null),null);
1250                        if(sct!=null) {
1251                                Iterator<Entry<Key, Object>> it = sct.entryIterator();
1252                                Entry<Key, Object> e;
1253                                UDF udf;
1254                                while(it.hasNext()){
1255                                        e = it.next();
1256                                        udf=Caster.toFunction(e.getValue(), null);
1257                                        if(udf!=null) customTypes.put(e.getKey().getLowerString(), new UDFCustomType(udf));
1258                                }
1259                        }
1260                }
1261                return customTypes.get(strType.trim().toLowerCase());
1262        }
1263
1264        @Override
1265        public boolean getCGIScopeReadonly() {
1266                if(!initCGIScopeReadonly) {
1267                        Object o = get(component,CGI_READONLY,null);
1268                        if(o!=null)cgiScopeReadonly=Caster.toBooleanValue(o,cgiScopeReadonly);
1269                        initCGIScopeReadonly=true;
1270                }
1271                return cgiScopeReadonly;
1272        }
1273        
1274
1275        public void setCGIScopeReadonly(boolean cgiScopeReadonly) {
1276                initCGIScopeReadonly=true;
1277                this.cgiScopeReadonly=cgiScopeReadonly;
1278        }
1279
1280}