001    package railo.runtime.listener;
002    
003    import java.util.ArrayList;
004    import java.util.Iterator;
005    import java.util.Map.Entry;
006    
007    import railo.commons.io.res.Resource;
008    import railo.commons.lang.ClassException;
009    import railo.commons.lang.StringUtil;
010    import railo.commons.lang.types.RefBoolean;
011    import railo.runtime.Mapping;
012    import railo.runtime.MappingImpl;
013    import railo.runtime.PageContext;
014    import railo.runtime.PageContextImpl;
015    import railo.runtime.PageSource;
016    import railo.runtime.config.Config;
017    import railo.runtime.config.ConfigImpl;
018    import railo.runtime.config.ConfigWeb;
019    import railo.runtime.config.ConfigWebImpl;
020    import railo.runtime.config.Constants;
021    import railo.runtime.db.ApplicationDataSource;
022    import railo.runtime.db.DBUtil;
023    import railo.runtime.db.DBUtil.DataSourceDefintion;
024    import railo.runtime.db.DataSource;
025    import railo.runtime.db.DataSourceImpl;
026    import railo.runtime.exp.ApplicationException;
027    import railo.runtime.exp.PageException;
028    import railo.runtime.net.s3.Properties;
029    import railo.runtime.net.s3.PropertiesImpl;
030    import railo.runtime.op.Caster;
031    import railo.runtime.op.Decision;
032    import railo.runtime.orm.ORMConfigurationImpl;
033    import railo.runtime.type.Array;
034    import railo.runtime.type.ArrayImpl;
035    import railo.runtime.type.Collection;
036    import railo.runtime.type.Collection.Key;
037    import railo.runtime.type.KeyImpl;
038    import railo.runtime.type.Struct;
039    import railo.runtime.type.StructImpl;
040    import railo.runtime.type.scope.Scope;
041    import railo.runtime.type.scope.Undefined;
042    import railo.runtime.type.util.KeyConstants;
043    import railo.runtime.type.util.ListUtil;
044    
045    public final class AppListenerUtil {
046            public static final Collection.Key ACCESS_KEY_ID = KeyImpl.intern("accessKeyId");
047            public static final Collection.Key AWS_SECRET_KEY = KeyImpl.intern("awsSecretKey");
048            public static final Collection.Key DEFAULT_LOCATION = KeyImpl.intern("defaultLocation");
049            public static final Collection.Key CONNECTION_STRING = KeyImpl.intern("connectionString");
050            
051            public static final Collection.Key BLOB = KeyImpl.intern("blob");
052            public static final Collection.Key CLOB = KeyImpl.intern("clob");
053            public static final Collection.Key CONNECTION_LIMIT = KeyImpl.intern("connectionLimit");
054            public static final Collection.Key CONNECTION_TIMEOUT = KeyImpl.intern("connectionTimeout");
055            public static final Collection.Key META_CACHE_TIMEOUT = KeyImpl.intern("metaCacheTimeout");
056            public static final Collection.Key TIMEZONE = KeyImpl.intern("timezone");
057            public static final Collection.Key ALLOW = KeyImpl.intern("allow");
058            public static final Collection.Key STORAGE = KeyImpl.intern("storage");
059            public static final Collection.Key READ_ONLY = KeyImpl.intern("readOnly");
060            public static final Collection.Key DATABASE = KeyImpl.intern("database");
061            
062            public static PageSource getApplicationPageSource(PageContext pc,PageSource requestedPage, String filename, int mode) {
063                    if(mode==ApplicationListener.MODE_CURRENT)return getApplicationPageSourceCurrent(requestedPage, filename);
064                    if(mode==ApplicationListener.MODE_ROOT)return getApplicationPageSourceRoot(pc, filename);
065                    return getApplicationPageSourceCurr2Root(pc, requestedPage, filename);
066            }
067            
068            public static PageSource getApplicationPageSourceCurrent(PageSource requestedPage, String filename) {
069                    PageSource res=requestedPage.getRealPage(filename);
070                if(res.exists()) return res;
071                    return null;
072            }
073            
074            public static PageSource getApplicationPageSourceRoot(PageContext pc, String filename) {
075                    PageSource ps = ((PageContextImpl)pc).getPageSourceExisting("/".concat(filename));
076                    if(ps!=null) return ps;
077                    return null;
078            }
079            
080            public static PageSource getApplicationPageSourceCurr2Root(PageContext pc,PageSource requestedPage, String filename) {
081                    PageSource ps=requestedPage.getRealPage(filename);
082                if(ps.exists()) { 
083                            return ps;
084                    }
085                Array arr=railo.runtime.type.util.ListUtil.listToArrayRemoveEmpty(requestedPage.getFullRealpath(),"/");
086                //Config config = pc.getConfig();
087                    for(int i=arr.size()-1;i>0;i--) {
088                        StringBuffer sb=new StringBuffer("/");
089                            for(int y=1;y<i;y++) {
090                                sb.append((String)arr.get(y,""));
091                                sb.append('/');
092                            }
093                            sb.append(filename);
094                            ps = ((PageContextImpl)pc).getPageSourceExisting(sb.toString());
095                            if(ps!=null) {
096                                    return ps;
097                            }
098                    }
099                    return null;
100            }
101            
102            
103    
104            public static PageSource getApplicationPageSource(PageContext pc,PageSource requestedPage, int mode, RefBoolean isCFC) {
105                    if(mode==ApplicationListener.MODE_CURRENT2ROOT)
106                            return getApplicationPageSourceCurr2Root(pc, requestedPage, isCFC);
107                    if(mode==ApplicationListener.MODE_CURRENT)
108                            return getApplicationPageSourceCurrent(requestedPage, isCFC);
109                    return getApplicationPageSourceRoot(pc, isCFC);
110            }
111            
112            public static PageSource getApplicationPageSourceCurrent(PageSource requestedPage, RefBoolean isCFC) {
113                    PageSource res=requestedPage.getRealPage(Constants.APP_CFC);
114                if(res.exists()) {
115                    isCFC.setValue(true);
116                    return res;
117                }
118                res=requestedPage.getRealPage(Constants.APP_CFM);
119                if(res.exists()) return res;
120                    return null;
121            }
122            
123            public static PageSource getApplicationPageSourceRoot(PageContext pc, RefBoolean isCFC) {
124                    PageSource ps = ((PageContextImpl)pc).getPageSourceExisting("/"+Constants.APP_CFC);
125                    if(ps!=null) {
126                            isCFC.setValue(true);
127                    return ps;
128                    }
129                    ps = ((PageContextImpl)pc).getPageSourceExisting("/"+Constants.APP_CFM);
130                    if(ps!=null) return ps;
131                    return null;
132            }
133            
134    
135            public static PageSource getApplicationPageSourceCurr2Root(PageContext pc,PageSource requestedPage, RefBoolean isCFC) {
136                PageSource res=requestedPage.getRealPage(Constants.APP_CFC);
137                if(res.exists()) {
138                    isCFC.setValue(true);
139                    return res;
140                }
141                res=requestedPage.getRealPage(Constants.APP_CFM);
142                if(res.exists()) return res;
143                
144                Array arr=railo.runtime.type.util.ListUtil.listToArrayRemoveEmpty(requestedPage.getFullRealpath(),"/");
145                    //Config config = pc.getConfig();
146                    String path;
147                    for(int i=arr.size()-1;i>0;i--) {
148                        StringBuilder sb=new StringBuilder("/");
149                            for(int y=1;y<i;y++) {
150                                sb.append((String)arr.get(y,""));
151                                sb.append('/');
152                            }
153                            path=sb.toString();
154                            res = ((PageContextImpl)pc).getPageSourceExisting(path.concat(Constants.APP_CFC));
155                            if(res!=null) {
156                                    isCFC.setValue(true);
157                                    return res;
158                            }
159                            res = ((PageContextImpl)pc).getPageSourceExisting(path.concat(Constants.APP_CFM));
160                            if(res!=null) return res;
161                    }
162                    return null;
163            }
164            
165            public static String toStringMode(int mode) {
166                    if(mode==ApplicationListener.MODE_CURRENT)      return "curr";
167                    if(mode==ApplicationListener.MODE_ROOT)         return "root";
168                    return "curr2root";
169            }
170    
171            public static String toStringType(ApplicationListener listener) {
172                    if(listener instanceof NoneAppListener)                 return "none";
173                    else if(listener instanceof MixedAppListener)   return "mixed";
174                    else if(listener instanceof ClassicAppListener) return "classic";
175                    else if(listener instanceof ModernAppListener)  return "modern";
176                    return "";
177            }
178            
179            public static DataSource[] toDataSources(Object o,DataSource[] defaultValue) {
180                    try {
181                            return toDataSources(o);
182                    } catch (Throwable t) {t.printStackTrace();
183                            return defaultValue;
184                    }
185            }
186    
187            public static DataSource[] toDataSources(Object o) throws PageException, ClassException {
188                    Struct sct = Caster.toStruct(o);
189                    Iterator<Entry<Key, Object>> it = sct.entryIterator();
190                    Entry<Key, Object> e;
191                    java.util.List<DataSource> dataSources=new ArrayList<DataSource>();
192                    while(it.hasNext()) {
193                            e = it.next();
194                            dataSources.add(toDataSource(e.getKey().getString().trim(), Caster.toStruct(e.getValue())));
195                    }
196                    return dataSources.toArray(new DataSource[dataSources.size()]);
197            }
198    
199            public static DataSource toDataSource(String name,Struct data) throws PageException, ClassException {
200                            String user = Caster.toString(data.get(KeyConstants._username,null),null);
201                            String pass = Caster.toString(data.get(KeyConstants._password,""),"");
202                            if(StringUtil.isEmpty(user)) {
203                                    user=null;
204                                    pass=null;
205                            }
206                            else {
207                                    user=user.trim();
208                                    pass=pass.trim();
209                            }
210                            
211                            // first check for {class:... , connectionString:...}
212                            Object oConnStr=data.get(CONNECTION_STRING,null);
213                            if(oConnStr!=null)
214                                    return ApplicationDataSource.getInstance(
215                                            name, 
216                                            Caster.toString(data.get(KeyConstants._class)), 
217                                            Caster.toString(oConnStr), 
218                                            user, pass,
219                                            Caster.toBooleanValue(data.get(BLOB,null),false),
220                                            Caster.toBooleanValue(data.get(CLOB,null),false), 
221                                            Caster.toIntValue(data.get(CONNECTION_LIMIT,null),-1), 
222                                            Caster.toIntValue(data.get(CONNECTION_TIMEOUT,null),1), 
223                                            Caster.toLongValue(data.get(META_CACHE_TIMEOUT,null),60000L), 
224                                            Caster.toTimeZone(data.get(TIMEZONE,null),null), 
225                                            Caster.toIntValue(data.get(ALLOW,null),DataSource.ALLOW_ALL),
226                                            Caster.toBooleanValue(data.get(STORAGE,null),false),
227                                            Caster.toBooleanValue(data.get(READ_ONLY,null),false));
228                            
229                            // then for {type:... , host:... , ...}
230                            String type=Caster.toString(data.get(KeyConstants._type));
231                            DataSourceDefintion dbt = DBUtil.getDataSourceDefintionForType(type, null);
232                            if(dbt==null) throw new ApplicationException("no datasource type ["+type+"] found");
233                            DataSourceImpl ds = new DataSourceImpl(
234                                            name, 
235                                            dbt.className, 
236                                            Caster.toString(data.get(KeyConstants._host)), 
237                                            dbt.connectionString,
238                                            Caster.toString(data.get(DATABASE)), 
239                                            Caster.toIntValue(data.get(KeyConstants._port,null),-1), 
240                                            user,pass, 
241                                            Caster.toIntValue(data.get(CONNECTION_LIMIT,null),-1), 
242                                            Caster.toIntValue(data.get(CONNECTION_TIMEOUT,null),1), 
243                                            Caster.toLongValue(data.get(META_CACHE_TIMEOUT,null),60000L), 
244                                            Caster.toBooleanValue(data.get(BLOB,null),false), 
245                                            Caster.toBooleanValue(data.get(CLOB,null),false), 
246                                            DataSource.ALLOW_ALL, 
247                                            Caster.toStruct(data.get(KeyConstants._custom,null),null,false), 
248                                            Caster.toBooleanValue(data.get(READ_ONLY,null),false), 
249                                            true, 
250                                            Caster.toBooleanValue(data.get(STORAGE,null),false), 
251                                            Caster.toTimeZone(data.get(TIMEZONE,null),null));
252    
253                            return ds;
254                    
255            }
256    
257            public static Mapping[] toMappings(ConfigWeb cw,Object o,Mapping[] defaultValue, Resource source) { 
258                    try {
259                            return toMappings(cw, o,source);
260                    } catch (Throwable t) {
261                            return defaultValue;
262                    }
263            }
264    
265            public static Mapping[] toMappings(ConfigWeb cw,Object o, Resource source) throws PageException {
266                    Struct sct = Caster.toStruct(o);
267                    Iterator<Entry<Key, Object>> it = sct.entryIterator();
268                    Entry<Key, Object> e;
269                    java.util.List<Mapping> mappings=new ArrayList<Mapping>();
270                    ConfigWebImpl config=(ConfigWebImpl) cw;
271                    String virtual,physical;
272                    while(it.hasNext()) {
273                            e = it.next();
274                            virtual=translateMappingVirtual(e.getKey().getString());
275                            physical=translateMappingPhysical(Caster.toString(e.getValue()),source);
276                            mappings.add(config.getApplicationMapping(virtual,physical));
277                            
278                    }
279                    return mappings.toArray(new Mapping[mappings.size()]);
280            }
281            
282    
283            private static String translateMappingPhysical(String path, Resource source) {
284                    source=source.getParentResource().getRealResource(path);
285                    if(source.exists()) return source.getAbsolutePath();
286                    return path;
287            }
288    
289            private static String translateMappingVirtual(String virtual) {
290                    virtual=virtual.replace('\\', '/');
291                    if(!StringUtil.startsWith(virtual,'/'))virtual="/".concat(virtual);
292                    return virtual;
293            }
294            
295    
296            public static Mapping[] toCustomTagMappings(ConfigWeb cw, Object o,Mapping[] defaultValue) {
297                    try {
298                            return toCustomTagMappings(cw, o);
299                    } catch (Throwable t) {
300                            return defaultValue;
301                    }
302            }
303    
304            public static Mapping[] toCustomTagMappings(ConfigWeb cw, Object o) throws PageException {
305                    Array array;
306                    if(o instanceof String){
307                            array=ListUtil.listToArrayRemoveEmpty(Caster.toString(o),',');
308                    }
309                    else if(o instanceof Struct){
310                            array=new ArrayImpl();
311                            Struct sct=(Struct) o;
312                            Iterator<Object> it = sct.valueIterator();
313                            while(it.hasNext()) {
314                                    array.append(it.next());
315                            }
316                    }
317                    else {
318                            array=Caster.toArray(o);
319                    }
320                    MappingImpl[] mappings=new MappingImpl[array.size()];
321                    ConfigWebImpl config=(ConfigWebImpl) cw;
322                    for(int i=0;i<mappings.length;i++) {
323                            
324                            mappings[i]=(MappingImpl) config.createCustomTagAppMappings("/"+i,Caster.toString(array.getE(i+1)).trim());
325                            /*mappings[i]=new MappingImpl(
326                                            config,"/"+i,
327                                            Caster.toString(array.getE(i+1)).trim(),
328                                            null,false,true,false,false,false
329                                            );*/
330                    }
331                    return mappings;
332            }
333    
334    
335            public static String toLocalMode(int mode, String defaultValue) {
336                    if(Undefined.MODE_LOCAL_OR_ARGUMENTS_ALWAYS==mode) return "modern";
337                    if(Undefined.MODE_LOCAL_OR_ARGUMENTS_ONLY_WHEN_EXISTS==mode)return "classic";
338                    return defaultValue;
339            }
340            
341            public static int toLocalMode(Object oMode, int defaultValue) {
342                    if(oMode==null) return defaultValue;
343                    
344                    if(Decision.isBoolean(oMode)) {
345                            if(Caster.toBooleanValue(oMode, false))
346                                    return Undefined.MODE_LOCAL_OR_ARGUMENTS_ALWAYS;
347                            return Undefined.MODE_LOCAL_OR_ARGUMENTS_ONLY_WHEN_EXISTS;
348                    }
349                    String strMode=Caster.toString(oMode,null);
350                    if("always".equalsIgnoreCase(strMode) || "modern".equalsIgnoreCase(strMode)) 
351                            return Undefined.MODE_LOCAL_OR_ARGUMENTS_ALWAYS;
352                    if("update".equalsIgnoreCase(strMode) || "classic".equalsIgnoreCase(strMode)) 
353                            return Undefined.MODE_LOCAL_OR_ARGUMENTS_ONLY_WHEN_EXISTS;
354                    return defaultValue;
355            }
356            
357            public static int toLocalMode(String strMode) throws ApplicationException {
358                    int lm = toLocalMode(strMode, -1);
359                    if(lm!=-1) return lm;
360                    throw new ApplicationException("invalid localMode definition ["+strMode+"] for tag "+Constants.CFAPP_NAME+"/"+Constants.APP_CFC+", valid values are [classic,modern,true,false]");
361            }
362    
363            public static short toSessionType(String str, short defaultValue) {
364                    if(!StringUtil.isEmpty(str,true)){
365                            str=str.trim().toLowerCase();
366                            if("cfml".equals(str)) return Config.SESSION_TYPE_CFML;
367                            if("j2ee".equals(str)) return Config.SESSION_TYPE_J2EE;
368                            if("cfm".equals(str)) return Config.SESSION_TYPE_CFML;
369                            if("jee".equals(str)) return Config.SESSION_TYPE_J2EE;
370                            if("j".equals(str)) return Config.SESSION_TYPE_J2EE;
371                            if("c".equals(str)) return Config.SESSION_TYPE_J2EE;
372                    }
373                    return defaultValue;
374            }
375    
376            public static short toSessionType(String str) throws ApplicationException {
377                    if(!StringUtil.isEmpty(str,true)){
378                            str=str.trim().toLowerCase();
379                            if("cfml".equals(str)) return Config.SESSION_TYPE_CFML;
380                            if("j2ee".equals(str)) return Config.SESSION_TYPE_J2EE;
381                            if("cfm".equals(str)) return Config.SESSION_TYPE_CFML;
382                            if("jee".equals(str)) return Config.SESSION_TYPE_J2EE;
383                            if("j".equals(str)) return Config.SESSION_TYPE_J2EE;
384                            if("c".equals(str)) return Config.SESSION_TYPE_J2EE;
385                    }
386                    throw new ApplicationException("invalid sessionType definition ["+str+"] for tag "+Constants.CFAPP_NAME+"/"+Constants.APP_CFC+", valid values are [cfml,j2ee]");
387            }
388            
389            public static Properties toS3(Struct sct) {
390                    String host=Caster.toString(sct.get(KeyConstants._host,null),null);
391                    if(StringUtil.isEmpty(host))host=Caster.toString(sct.get(KeyConstants._server,null),null);
392                    
393                    return toS3(
394                                    Caster.toString(sct.get(ACCESS_KEY_ID,null),null),
395                                    Caster.toString(sct.get(AWS_SECRET_KEY,null),null),
396                                    Caster.toString(sct.get(DEFAULT_LOCATION,null),null),
397                                    host
398                            );
399            }
400    
401            public static Properties toS3(String accessKeyId, String awsSecretKey, String defaultLocation, String host) {
402                    PropertiesImpl s3 = new PropertiesImpl();
403                    if(!StringUtil.isEmpty(accessKeyId))s3.setAccessKeyId(accessKeyId);
404                    if(!StringUtil.isEmpty(awsSecretKey))s3.setSecretAccessKey(awsSecretKey);
405                    if(!StringUtil.isEmpty(defaultLocation))s3.setDefaultLocation(defaultLocation);
406                    if(!StringUtil.isEmpty(host))s3.setHost(host);
407                    return s3;
408            }
409    
410            public static void setORMConfiguration(PageContext pc, ApplicationContext ac,Struct sct) throws PageException {
411                    if(sct==null)sct=new StructImpl();
412                    Resource res=pc.getCurrentTemplatePageSource().getResourceTranslated(pc).getParentResource();
413                    ConfigImpl config=(ConfigImpl) pc.getConfig();
414                    ac.setORMConfiguration(ORMConfigurationImpl.load(config,ac,sct,res,config.getORMConfig()));
415                    
416                    // datasource
417                    Object o = sct.get(KeyConstants._datasource,null);
418                    if(o!=null) ac.setORMDatasource(Caster.toString(o));
419            }
420            
421            
422            /**
423             * translate int definition of script protect to string definition
424             * @param scriptProtect
425             * @return
426             */
427            public static String translateScriptProtect(int scriptProtect) {
428                    if(scriptProtect==ApplicationContext.SCRIPT_PROTECT_NONE) return "none";
429                    if(scriptProtect==ApplicationContext.SCRIPT_PROTECT_ALL) return "all";
430                    
431                    Array arr=new ArrayImpl();
432                    if((scriptProtect&ApplicationContext.SCRIPT_PROTECT_CGI)>0) arr.appendEL("cgi");
433                    if((scriptProtect&ApplicationContext.SCRIPT_PROTECT_COOKIE)>0) arr.appendEL("cookie");
434                    if((scriptProtect&ApplicationContext.SCRIPT_PROTECT_FORM)>0) arr.appendEL("form");
435                    if((scriptProtect&ApplicationContext.SCRIPT_PROTECT_URL)>0) arr.appendEL("url");
436                    
437                    
438                    
439                    try {
440                            return ListUtil.arrayToList(arr, ",");
441                    } catch (PageException e) {
442                            return "none";
443                    } 
444            }
445            
446    
447            /**
448             * translate string definition of script protect to int definition
449             * @param scriptProtect
450             * @return
451             */
452            public static int translateScriptProtect(String strScriptProtect) {
453                    strScriptProtect=strScriptProtect.toLowerCase().trim();
454                    
455                    if("none".equals(strScriptProtect)) return ApplicationContext.SCRIPT_PROTECT_NONE;
456                    if("no".equals(strScriptProtect)) return ApplicationContext.SCRIPT_PROTECT_NONE;
457                    if("false".equals(strScriptProtect)) return ApplicationContext.SCRIPT_PROTECT_NONE;
458                    
459                    if("all".equals(strScriptProtect)) return ApplicationContext.SCRIPT_PROTECT_ALL;
460                    if("true".equals(strScriptProtect)) return ApplicationContext.SCRIPT_PROTECT_ALL;
461                    if("yes".equals(strScriptProtect)) return ApplicationContext.SCRIPT_PROTECT_ALL;
462                    
463                    String[] arr = ListUtil.listToStringArray(strScriptProtect, ',');
464                    String item;
465                    int scriptProtect=0;
466                    for(int i=0;i<arr.length;i++) {
467                            item=arr[i].trim();
468                            if("cgi".equals(item) && (scriptProtect&ApplicationContext.SCRIPT_PROTECT_CGI)==0)
469                                    scriptProtect+=ApplicationContext.SCRIPT_PROTECT_CGI;
470                            else if("cookie".equals(item) && (scriptProtect&ApplicationContext.SCRIPT_PROTECT_COOKIE)==0)
471                                    scriptProtect+=ApplicationContext.SCRIPT_PROTECT_COOKIE;
472                            else if("form".equals(item) && (scriptProtect&ApplicationContext.SCRIPT_PROTECT_FORM)==0)
473                                    scriptProtect+=ApplicationContext.SCRIPT_PROTECT_FORM;
474                            else if("url".equals(item) && (scriptProtect&ApplicationContext.SCRIPT_PROTECT_URL)==0)
475                                    scriptProtect+=ApplicationContext.SCRIPT_PROTECT_URL;
476                    }
477                    return scriptProtect;
478            }
479            
480    
481            public static String translateLoginStorage(int loginStorage) {
482                    if(loginStorage==Scope.SCOPE_SESSION) return "session";
483                    return "cookie";
484            }
485            
486    
487            public static int translateLoginStorage(String strLoginStorage, int defaultValue) {
488                    strLoginStorage=strLoginStorage.toLowerCase().trim();
489                if(strLoginStorage.equals("session"))return Scope.SCOPE_SESSION;
490                if(strLoginStorage.equals("cookie"))return Scope.SCOPE_COOKIE;
491                return defaultValue;
492            }
493            
494    
495            public static int translateLoginStorage(String strLoginStorage) throws ApplicationException {
496                    int ls=translateLoginStorage(strLoginStorage, -1);
497                    if(ls!=-1) return ls;
498                throw new ApplicationException("invalid loginStorage definition ["+strLoginStorage+"], valid values are [session,cookie]");
499            }
500    }
501    
502