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