001    package railo.runtime.tag;
002    
003    import railo.commons.lang.ClassException;
004    import railo.commons.io.res.Resource;
005    import railo.commons.io.res.util.ResourceUtil;
006    import railo.commons.lang.StringUtil;
007    import railo.runtime.Mapping;
008    import railo.runtime.config.Config;
009    import railo.runtime.exp.ApplicationException;
010    import railo.runtime.exp.PageException;
011    import railo.runtime.ext.tag.TagImpl;
012    import railo.runtime.listener.AppListenerUtil;
013    import railo.runtime.listener.ApplicationContextPro;
014    import railo.runtime.listener.ClassicApplicationContext;
015    import railo.runtime.listener.ModernApplicationContext;
016    import railo.runtime.op.Caster;
017    import railo.runtime.orm.ORMUtil;
018    import railo.runtime.type.Struct;
019    import railo.runtime.type.UDF;
020    import railo.runtime.type.dt.TimeSpan;
021    import railo.runtime.type.scope.Scope;
022    
023    /**
024    * Defines scoping for a CFML application, enables or disables storing client variables, 
025    *                       and specifies a client variable storage mechanism. 
026    *                       By default, client variables are disabled. Also, enables session variables and sets timeouts 
027    *                       for session and application variables. Session and application variables are stored in memory.
028    *
029    *
030    *
031    **/
032    public final class Application extends TagImpl {
033    
034            
035    
036            private static final int ACTION_CREATE = 0;
037            private static final int ACTION_UPDATE = 1;
038        
039            private Boolean setClientCookies;
040            private Boolean setDomainCookies;
041            private Boolean setSessionManagement;
042            private String clientstorage;
043            private String sessionstorage;
044            private Boolean setClientManagement;
045            private TimeSpan sessionTimeout;
046            private TimeSpan clientTimeout;
047            private TimeSpan applicationTimeout;
048            private Mapping[] mappings;
049            private Mapping[] customTagMappings;
050            private Mapping[] componentMappings;
051            private String secureJsonPrefix;
052            private Boolean bufferOutput;
053            private Boolean secureJson;
054            private String scriptrotect;
055            private Object datasource;
056            private Object defaultdatasource;
057            private int loginstorage=Scope.SCOPE_UNDEFINED;
058            
059            //ApplicationContextImpl appContext;
060        private String name="";
061            private int action=ACTION_CREATE;
062            private int localMode=-1;
063            private short sessionType=-1;
064            private boolean sessionCluster;
065            private boolean clientCluster;
066    
067            private boolean ormenabled;
068            private Struct ormsettings;
069            private Struct s3;
070            
071            private Boolean triggerDataMember=null;
072            private String cacheFunction;
073            private String cacheQuery;
074            private String cacheTemplate;
075            private String cacheObject;
076            private String cacheResource;
077            private Struct datasources;
078            private UDF onmissingtemplate;
079            
080         
081        @Override
082        public void release() {
083            super.release();
084            setClientCookies=null;
085            setDomainCookies=null;
086            setSessionManagement=null;
087            clientstorage=null;
088            sessionstorage=null;
089            setClientManagement=null;
090            sessionTimeout=null;
091            clientTimeout=null;
092            applicationTimeout=null;
093            mappings=null;
094            customTagMappings=null;
095            componentMappings=null;
096            bufferOutput=null;
097            secureJson=null;
098            secureJsonPrefix=null;
099            loginstorage=Scope.SCOPE_UNDEFINED;
100            scriptrotect=null;
101            datasource=null;
102            defaultdatasource=null;
103            datasources=null;
104            this.name="";
105            action=ACTION_CREATE;
106            localMode=-1;
107            sessionType=-1;
108            sessionCluster=false;
109            clientCluster=false;
110            
111            ormenabled=false;
112            ormsettings=null;
113            s3=null;
114            //appContext=null;
115            
116            triggerDataMember=null;
117    
118            cacheFunction=null;
119            cacheQuery=null;
120            cacheTemplate=null;
121            cacheObject=null;
122            cacheResource=null;
123            onmissingtemplate=null;
124        }
125        
126        /** set the value setclientcookies
127            *  Yes or No. Yes enables client cookies. Default is Yes. If you set this attribute to 
128            *               "No", CFML does not automatically send the CFID and CFTOKEN cookies to the client browser;
129            *               you must manually code CFID and CFTOKEN on the URL for every page that uses Session or Client variables.
130            * @param setClientCookies value to set
131            **/
132            public void setSetclientcookies(boolean setClientCookies)       {
133                    this.setClientCookies=setClientCookies?Boolean.TRUE:Boolean.FALSE;
134                //getAppContext().setSetClientCookies(setClientCookies);
135            }
136    
137        /** set the value setdomaincookies
138            *  Yes or No. Sets the CFID and CFTOKEN cookies for a domain, not just a single host. 
139            *               Applications that are running on clusters must set this value to Yes. The default is No.
140            * @param setDomainCookies value to set
141            **/
142            public void setSetdomaincookies(boolean setDomainCookies)       {
143                    this.setDomainCookies=setDomainCookies?Boolean.TRUE:Boolean.FALSE;
144                //getAppContext().setSetDomainCookies(setDomainCookies);
145            }
146    
147            /** set the value sessionmanagement
148            *  Yes or No. Yes enables session variables. Default is No.
149            * @param setSessionManagement value to set
150            **/
151            public void setSessionmanagement(boolean setSessionManagement)  {
152                    this.setSessionManagement=setSessionManagement?Boolean.TRUE:Boolean.FALSE;
153                //getAppContext().setSetSessionManagement(setSessionManagement);
154            }
155    
156        
157            /**
158             * @param datasource the datasource to set
159             * @throws PageException 
160             */
161            public void setDatasource(Object datasource) throws PageException {
162                    this.datasource = ModernApplicationContext.toDefaultDatasource(datasource);
163            }
164            
165            public void setDefaultdatasource(Object defaultdatasource) throws PageException {
166                    this.defaultdatasource =  ModernApplicationContext.toDefaultDatasource(defaultdatasource);
167            }
168            
169            public void setDatasources(Struct datasources) {
170                    this.datasources = datasources;
171            }
172            
173            public void setLocalmode(String strLocalMode) throws ApplicationException {
174                    this.localMode = AppListenerUtil.toLocalMode(strLocalMode);
175                    
176            }
177    
178            /** set the value clientstorage
179            *  Specifies how Railo stores client variables
180            * @param clientstorage value to set
181            **/
182            public void setClientstorage(String clientstorage)      {
183                    this.clientstorage=clientstorage;
184            }
185    
186            public void setSessionstorage(String sessionstorage)    {
187                    this.sessionstorage=sessionstorage;
188            }
189    
190            /** set the value clientmanagement
191            *  Yes or No. Enables client variables. Default is No.
192            * @param setClientManagement value to set
193            **/
194            public void setClientmanagement(boolean setClientManagement)    {
195                    this.setClientManagement=setClientManagement?Boolean.TRUE:Boolean.FALSE;
196                //getAppContext().setSetClientManagement(setClientManagement);
197            }
198    
199            /** set the value sessiontimeout
200            *  Enter the CreateTimeSpan function and values in days, hours, minutes, and seconds, separated 
201            *               by commas, to specify the lifespan of session variables.
202            * @param sessionTimeout value to set
203            **/
204            public void setSessiontimeout(TimeSpan sessionTimeout)  {
205                    this.sessionTimeout=sessionTimeout;
206            }
207            public void setSessiontype(String sessionType) throws ApplicationException      {
208                    this.sessionType=AppListenerUtil.toSessionType(sessionType);
209            }
210            public void setClientcluster(boolean clientCluster) {
211                    this.clientCluster=clientCluster;
212            }
213            public void setSessioncluster(boolean sessionCluster) {
214                    this.sessionCluster=sessionCluster;
215            }
216            
217            public void setClienttimeout(TimeSpan clientTimeout)    {
218                    this.clientTimeout=clientTimeout;
219            }
220            
221    
222            public void setCachefunction(String cacheFunction)      {
223                    if(StringUtil.isEmpty(cacheFunction,true)) return;
224                    this.cacheFunction=cacheFunction.trim();
225            }
226            public void setCachequery(String cacheQuery)    {
227                    if(StringUtil.isEmpty(cacheQuery,true)) return;
228                    this.cacheQuery=cacheQuery.trim();
229            }
230            public void setCachetemplate(String cacheTemplate)      {
231                    if(StringUtil.isEmpty(cacheTemplate,true)) return;
232                    this.cacheTemplate=cacheTemplate.trim();
233            }
234            public void setCacheobject(String cacheObject)  {
235                    if(StringUtil.isEmpty(cacheObject,true)) return;
236                    this.cacheObject=cacheObject.trim();
237            }
238            public void setCacheresource(String cacheResource)      {
239                    if(StringUtil.isEmpty(cacheResource,true)) return;
240                    this.cacheResource=cacheResource.trim();
241            }
242            
243    
244            public void setTriggerdatamember(boolean triggerDataMember)     {
245                    this.triggerDataMember=triggerDataMember?Boolean.TRUE:Boolean.FALSE;
246            }
247            public void setInvokeimplicitaccessor(boolean invokeimplicitaccessor)   {
248                    setTriggerdatamember(invokeimplicitaccessor);
249            }
250    
251            /**
252             * @param ormenabled the ormenabled to set
253             */
254            public void setOrmenabled(boolean ormenabled) {
255                    this.ormenabled = ormenabled;
256            }
257    
258            /**
259             * @param ormsettings the ormsettings to set
260             */
261            public void setOrmsettings(Struct ormsettings) {
262                    this.ormsettings = ormsettings;
263            }
264    
265            /**
266             * @param s3 the s3 to set
267             */
268            public void setS3(Struct s3) {
269                    this.s3 = s3;
270            }
271    
272            /** set the value applicationtimeout
273            *  Enter the CreateTimeSpan function and values in days, hours, minutes, and seconds, separated 
274            *               by commas, to specify the lifespan of application variables. 
275            * @param applicationTimeout value to set
276            **/
277            public void setApplicationtimeout(TimeSpan applicationTimeout)  {
278                    this.applicationTimeout=applicationTimeout;
279                //getAppContext().setApplicationTimeout(applicationTimeout);
280            }
281    
282            /** set the value name
283            *  The name of your application. This name can be up to 64 characters long.
284            *               Required for application and session variables, optional for client variables
285            * @param name value to set
286            **/
287            public void setName(String name)        {
288                this.name=name;
289            }
290            
291            public void setAction(String strAction) throws ApplicationException     {
292                    strAction=strAction.toLowerCase();
293            if(strAction.equals("create"))action=ACTION_CREATE;
294            else if(strAction.equals("update")) action=ACTION_UPDATE;
295            else throw new ApplicationException("invalid action definition ["+strAction+"] for tag application, valid values are [create,update]");
296        
297            }
298            
299            public void setMappings(Struct mappings) throws PageException   {
300                this.mappings=AppListenerUtil.toMappings(pageContext.getConfig(), mappings,getSource());
301                    //getAppContext().setMappings(AppListenerUtil.toMappings(pageContext, mappings));
302            }
303            
304            public void setCustomtagpaths(Object mappings) throws PageException     {
305                this.customTagMappings=AppListenerUtil.toCustomTagMappings(pageContext.getConfig(), mappings);
306            }
307            
308            public void setComponentpaths(Object mappings) throws PageException     {
309                this.componentMappings=AppListenerUtil.toCustomTagMappings(pageContext.getConfig(), mappings);
310                    //getAppContext().setCustomTagMappings(AppListenerUtil.toCustomTagMappings(pageContext, mappings));
311            }
312            
313    
314            public void setSecurejsonprefix(String secureJsonPrefix)        {
315                    this.secureJsonPrefix=secureJsonPrefix;
316                //getAppContext().setSecureJsonPrefix(secureJsonPrefix);
317            }
318            public void setSecurejson(boolean secureJson)   {
319                    this.secureJson=secureJson?Boolean.TRUE:Boolean.FALSE;
320                //getAppContext().setSecureJson(secureJson);
321            }
322            public void setBufferoutput(boolean bufferOutput)       {
323                    this.bufferOutput=bufferOutput?Boolean.TRUE:Boolean.FALSE;
324                //getAppContext().setSecureJson(secureJson);
325            }
326            
327        /**
328         * @param loginstorage The loginstorage to set.
329         * @throws ApplicationException
330         */
331        public void setLoginstorage(String loginstorage) throws ApplicationException {
332            loginstorage=loginstorage.toLowerCase();
333            if(loginstorage.equals("session"))this.loginstorage=Scope.SCOPE_SESSION;
334            else if(loginstorage.equals("cookie"))this.loginstorage=Scope.SCOPE_COOKIE;
335            else throw new ApplicationException("invalid loginStorage definition ["+loginstorage+"] for tag application, valid values are [session,cookie]");
336        }
337            /**
338             * @param scriptrotect the scriptrotect to set
339             */                     
340            public void setScriptprotect(String strScriptrotect) {
341                    this.scriptrotect=strScriptrotect;
342                    //getAppContext().setScriptProtect(strScriptrotect);
343            }
344    
345            public void setOnmissingtemplate(Object oUDF) throws PageException {
346                    this.onmissingtemplate=Caster.toFunction(oUDF);
347            }
348    
349            @Override
350            public int doStartTag() throws PageException    {
351            
352            ApplicationContextPro ac;
353            boolean initORM;
354            if(action==ACTION_CREATE){
355                    ac=new ClassicApplicationContext(pageContext.getConfig(),name,false,
356                                    pageContext.getCurrentPageSource().getResourceTranslated(pageContext));
357                    initORM=set(ac);
358                    pageContext.setApplicationContext(ac);
359            }
360            else {
361                    ac=(ApplicationContextPro) pageContext.getApplicationContext();
362                    initORM=set(ac);
363            }
364            
365            if(initORM) ORMUtil.resetEngine(pageContext,false);
366            
367            return SKIP_BODY; 
368            }
369    
370            private Resource getSource() throws PageException {
371                    return ResourceUtil.getResource(pageContext,pageContext.getCurrentPageSource());
372            }
373    
374            private boolean set(ApplicationContextPro ac) throws PageException {
375                    if(applicationTimeout!=null)                    ac.setApplicationTimeout(applicationTimeout);
376                    if(sessionTimeout!=null)                                ac.setSessionTimeout(sessionTimeout);
377                    if(clientTimeout!=null)                         ac.setClientTimeout(clientTimeout);
378                    if(clientstorage!=null) {
379                            ac.setClientstorage(clientstorage);
380                    }
381                    if(sessionstorage!=null)        {
382                            ac.setSessionstorage(sessionstorage);
383                    }
384                    if(customTagMappings!=null)                             ac.setCustomTagMappings(customTagMappings);
385                    if(componentMappings!=null)                             ac.setComponentMappings(componentMappings);
386                    if(mappings!=null)                                              ac.setMappings(mappings);
387                    if(loginstorage!=Scope.SCOPE_UNDEFINED) ac.setLoginStorage(loginstorage);
388                    if(!StringUtil.isEmpty(datasource))             {
389                            ac.setDefDataSource(datasource);
390                            ac.setORMDataSource(datasource);
391                    }
392                    if(!StringUtil.isEmpty(defaultdatasource))ac.setDefDataSource(defaultdatasource);
393                    if(datasources!=null){
394                            try {
395                                    ac.setDataSources(AppListenerUtil.toDataSources(datasources));
396                            } 
397                            catch (ClassException e) {
398                                    throw Caster.toPageException(e);
399                            }
400                    }
401                    
402                    if(onmissingtemplate!=null && ac instanceof ClassicApplicationContext){
403                            ((ClassicApplicationContext)ac).setOnMissingTemplate(onmissingtemplate);
404                    }
405                    
406                    
407                    if(scriptrotect!=null)                                  ac.setScriptProtect(AppListenerUtil.translateScriptProtect(scriptrotect));
408                    if(bufferOutput!=null)                                  ac.setBufferOutput(bufferOutput.booleanValue());
409                    if(secureJson!=null)                                    ac.setSecureJson(secureJson.booleanValue());
410                    if(secureJsonPrefix!=null)                              ac.setSecureJsonPrefix(secureJsonPrefix);
411                    if(setClientCookies!=null)                              ac.setSetClientCookies(setClientCookies.booleanValue());
412                    if(setClientManagement!=null)                   ac.setSetClientManagement(setClientManagement.booleanValue());
413                    if(setDomainCookies!=null)                              ac.setSetDomainCookies(setDomainCookies.booleanValue());
414                    if(setSessionManagement!=null)                  ac.setSetSessionManagement(setSessionManagement.booleanValue());
415                    if(localMode!=-1)                                               ac.setLocalMode(localMode);
416                    if(sessionType!=-1)                                     ac.setSessionType(sessionType);
417                    if(triggerDataMember!=null)                     ac.setTriggerComponentDataMember(triggerDataMember.booleanValue());
418                    
419                    if(cacheFunction!=null)                                 ac.setDefaultCacheName(Config.CACHE_DEFAULT_FUNCTION, cacheFunction);
420                    if(cacheObject!=null)                                   ac.setDefaultCacheName(Config.CACHE_DEFAULT_OBJECT, cacheObject);
421                    if(cacheQuery!=null)                                    ac.setDefaultCacheName(Config.CACHE_DEFAULT_QUERY, cacheQuery);
422                    if(cacheResource!=null)                                 ac.setDefaultCacheName(Config.CACHE_DEFAULT_RESOURCE, cacheResource);
423                    if(cacheTemplate!=null)                                 ac.setDefaultCacheName(Config.CACHE_DEFAULT_TEMPLATE, cacheTemplate);
424                    
425                    ac.setClientCluster(clientCluster);
426                    ac.setSessionCluster(sessionCluster);
427                    if(s3!=null)                                                    ac.setS3(AppListenerUtil.toS3(s3));
428                    
429                    // ORM
430                    boolean initORM=false;
431                    ac.setORMEnabled(ormenabled);
432                    if(ormenabled) {
433                            initORM=true;
434                            AppListenerUtil.setORMConfiguration(pageContext, ac, ormsettings);
435                    }
436                    
437                    
438                    return initORM;
439            }
440    
441            @Override
442            public int doEndTag()   {
443                    return EVAL_PAGE;
444            }
445    
446    }