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; 020 021 022import java.io.IOException; 023import java.io.OutputStream; 024import java.nio.charset.Charset; 025import java.sql.Statement; 026import java.util.ArrayList; 027import java.util.Date; 028import java.util.Enumeration; 029import java.util.HashSet; 030import java.util.LinkedList; 031import java.util.List; 032import java.util.Locale; 033import java.util.Map; 034import java.util.Map.Entry; 035import java.util.Set; 036import java.util.Stack; 037import java.util.TimeZone; 038import java.util.concurrent.ConcurrentHashMap; 039 040import javax.servlet.Servlet; 041import javax.servlet.ServletConfig; 042import javax.servlet.ServletContext; 043import javax.servlet.ServletException; 044import javax.servlet.ServletRequest; 045import javax.servlet.ServletResponse; 046import javax.servlet.http.HttpServlet; 047import javax.servlet.http.HttpServletRequest; 048import javax.servlet.http.HttpServletResponse; 049import javax.servlet.http.HttpSession; 050import javax.servlet.jsp.JspException; 051import javax.servlet.jsp.JspWriter; 052import javax.servlet.jsp.tagext.BodyContent; 053import javax.servlet.jsp.tagext.BodyTag; 054import javax.servlet.jsp.tagext.Tag; 055import javax.servlet.jsp.tagext.TryCatchFinally; 056 057import lucee.commons.db.DBUtil; 058import lucee.commons.io.BodyContentStack; 059import lucee.commons.io.CharsetUtil; 060import lucee.commons.io.IOUtil; 061import lucee.commons.io.res.Resource; 062import lucee.commons.io.res.util.ResourceClassLoader; 063import lucee.commons.lang.ExceptionUtil; 064import lucee.commons.lang.PhysicalClassLoader; 065import lucee.commons.lang.SizeOf; 066import lucee.commons.lang.StringUtil; 067import lucee.commons.lang.SystemOut; 068import lucee.commons.lang.mimetype.MimeType; 069import lucee.commons.lang.types.RefBoolean; 070import lucee.commons.lang.types.RefBooleanImpl; 071import lucee.commons.lock.KeyLock; 072import lucee.commons.lock.Lock; 073import lucee.commons.net.HTTPUtil; 074import lucee.intergral.fusiondebug.server.FDSignal; 075import lucee.runtime.cache.tag.CacheHandler; 076import lucee.runtime.cache.tag.CacheHandlerFactory; 077import lucee.runtime.cache.tag.CacheItem; 078import lucee.runtime.cache.tag.include.IncludeCacheItem; 079import lucee.runtime.component.ComponentLoader; 080import lucee.runtime.config.Config; 081import lucee.runtime.config.ConfigImpl; 082import lucee.runtime.config.ConfigWeb; 083import lucee.runtime.config.ConfigWebImpl; 084import lucee.runtime.config.ConfigWebUtil; 085import lucee.runtime.config.Constants; 086import lucee.runtime.config.NullSupportHelper; 087import lucee.runtime.db.DataSource; 088import lucee.runtime.db.DataSourceManager; 089import lucee.runtime.db.DatasourceConnection; 090import lucee.runtime.db.DatasourceConnectionPool; 091import lucee.runtime.db.DatasourceManagerImpl; 092import lucee.runtime.debug.ActiveLock; 093import lucee.runtime.debug.ActiveQuery; 094import lucee.runtime.debug.DebugCFMLWriter; 095import lucee.runtime.debug.DebugEntryTemplate; 096import lucee.runtime.debug.Debugger; 097import lucee.runtime.debug.DebuggerImpl; 098import lucee.runtime.debug.DebuggerPro; 099import lucee.runtime.dump.DumpUtil; 100import lucee.runtime.dump.DumpWriter; 101import lucee.runtime.engine.ExecutionLog; 102import lucee.runtime.err.ErrorPage; 103import lucee.runtime.err.ErrorPageImpl; 104import lucee.runtime.err.ErrorPagePool; 105import lucee.runtime.exp.Abort; 106import lucee.runtime.exp.ApplicationException; 107import lucee.runtime.exp.CasterException; 108import lucee.runtime.exp.DatabaseException; 109import lucee.runtime.exp.ExceptionHandler; 110import lucee.runtime.exp.ExpressionException; 111import lucee.runtime.exp.MissingIncludeException; 112import lucee.runtime.exp.PageException; 113import lucee.runtime.exp.PageExceptionBox; 114import lucee.runtime.exp.PageExceptionImpl; 115import lucee.runtime.exp.PageServletException; 116import lucee.runtime.functions.dynamicEvaluation.Serialize; 117import lucee.runtime.interpreter.CFMLExpressionInterpreter; 118import lucee.runtime.interpreter.VariableInterpreter; 119import lucee.runtime.listener.AppListenerUtil; 120import lucee.runtime.listener.ApplicationContext; 121import lucee.runtime.listener.ApplicationContextPro; 122import lucee.runtime.listener.ApplicationListener; 123import lucee.runtime.listener.ClassicApplicationContext; 124import lucee.runtime.listener.JavaSettingsImpl; 125import lucee.runtime.listener.ModernAppListenerException; 126import lucee.runtime.monitor.RequestMonitor; 127import lucee.runtime.net.ftp.FTPPool; 128import lucee.runtime.net.ftp.FTPPoolImpl; 129import lucee.runtime.net.http.HTTPServletRequestWrap; 130import lucee.runtime.net.http.ReqRspUtil; 131import lucee.runtime.op.Caster; 132import lucee.runtime.op.Decision; 133import lucee.runtime.op.Operator; 134import lucee.runtime.orm.ORMConfiguration; 135import lucee.runtime.orm.ORMEngine; 136import lucee.runtime.orm.ORMSession; 137import lucee.runtime.query.QueryCache; 138import lucee.runtime.rest.RestRequestListener; 139import lucee.runtime.rest.RestUtil; 140import lucee.runtime.security.Credential; 141import lucee.runtime.security.CredentialImpl; 142import lucee.runtime.security.ScriptProtect; 143import lucee.runtime.tag.Login; 144import lucee.runtime.tag.TagHandlerPool; 145import lucee.runtime.tag.TagUtil; 146import lucee.runtime.type.Array; 147import lucee.runtime.type.Collection; 148import lucee.runtime.type.Collection.Key; 149import lucee.runtime.type.Iterator; 150import lucee.runtime.type.KeyImpl; 151import lucee.runtime.type.Query; 152import lucee.runtime.type.SVArray; 153import lucee.runtime.type.Sizeable; 154import lucee.runtime.type.Struct; 155import lucee.runtime.type.StructImpl; 156import lucee.runtime.type.UDF; 157import lucee.runtime.type.UDFPlus; 158import lucee.runtime.type.it.ItAsEnum; 159import lucee.runtime.type.ref.Reference; 160import lucee.runtime.type.ref.VariableReference; 161import lucee.runtime.type.scope.Application; 162import lucee.runtime.type.scope.Argument; 163import lucee.runtime.type.scope.ArgumentImpl; 164import lucee.runtime.type.scope.CGI; 165import lucee.runtime.type.scope.CGIImpl; 166import lucee.runtime.type.scope.CGIImplReadOnly; 167import lucee.runtime.type.scope.Client; 168import lucee.runtime.type.scope.ClosureScope; 169import lucee.runtime.type.scope.Cluster; 170import lucee.runtime.type.scope.Cookie; 171import lucee.runtime.type.scope.CookieImpl; 172import lucee.runtime.type.scope.Form; 173import lucee.runtime.type.scope.FormImpl; 174import lucee.runtime.type.scope.Local; 175import lucee.runtime.type.scope.LocalNotSupportedScope; 176import lucee.runtime.type.scope.Request; 177import lucee.runtime.type.scope.RequestImpl; 178import lucee.runtime.type.scope.Scope; 179import lucee.runtime.type.scope.ScopeContext; 180import lucee.runtime.type.scope.ScopeFactory; 181import lucee.runtime.type.scope.ScopeSupport; 182import lucee.runtime.type.scope.Server; 183import lucee.runtime.type.scope.Session; 184import lucee.runtime.type.scope.Threads; 185import lucee.runtime.type.scope.URL; 186import lucee.runtime.type.scope.URLForm; 187import lucee.runtime.type.scope.URLImpl; 188import lucee.runtime.type.scope.Undefined; 189import lucee.runtime.type.scope.UndefinedImpl; 190import lucee.runtime.type.scope.UrlFormImpl; 191import lucee.runtime.type.scope.Variables; 192import lucee.runtime.type.scope.VariablesImpl; 193import lucee.runtime.type.util.ArrayUtil; 194import lucee.runtime.type.util.CollectionUtil; 195import lucee.runtime.type.util.KeyConstants; 196import lucee.runtime.util.PageContextUtil; 197import lucee.runtime.util.VariableUtil; 198import lucee.runtime.util.VariableUtilImpl; 199import lucee.runtime.writer.BodyContentUtil; 200import lucee.runtime.writer.CFMLWriter; 201import lucee.runtime.writer.DevNullBodyContent; 202 203import org.apache.oro.text.regex.MalformedPatternException; 204import org.apache.oro.text.regex.Pattern; 205import org.apache.oro.text.regex.PatternMatcherInput; 206import org.apache.oro.text.regex.Perl5Compiler; 207import org.apache.oro.text.regex.Perl5Matcher; 208 209/** 210 * page context for every page object. 211 * the PageContext is a jsp page context expanded by CFML functionality. 212 * for example you have the method getSession to get jsp combatible session object (HTTPSession) 213 * and with sessionScope() you get CFML combatible session object (Struct,Scope). 214 */ 215public final class PageContextImpl extends PageContext implements Sizeable { 216 217 private static final RefBoolean DUMMY_BOOL = new RefBooleanImpl(false); 218 219 private static int counter=0; 220 221 /** 222 * Field <code>pathList</code> 223 */ 224 private LinkedList<UDF> udfs=new LinkedList<UDF>(); 225 private LinkedList<PageSource> pathList=new LinkedList<PageSource>(); 226 private LinkedList<PageSource> includePathList=new LinkedList<PageSource>(); 227 private Set<PageSource> includeOnce=new HashSet<PageSource>(); 228 229 /** 230 * Field <code>executionTime</code> 231 */ 232 protected long executionTime=0; 233 234 private HTTPServletRequestWrap req; 235 private HttpServletResponse rsp; 236 private HttpServlet servlet; 237 238 private JspWriter writer; 239 private JspWriter forceWriter; 240 private BodyContentStack bodyContentStack; 241 private DevNullBodyContent devNull; 242 243 private ConfigWebImpl config; 244 //private DataSourceManager manager; 245 //private CFMLCompilerImpl compiler; 246 247 // Scopes 248 private ScopeContext scopeContext; 249 private Variables variablesRoot=new VariablesImpl();//ScopeSupport(false,"variables",Scope.SCOPE_VARIABLES); 250 private Variables variables=variablesRoot;//new ScopeSupport("variables",Scope.SCOPE_VARIABLES); 251 private Undefined undefined; 252 253 private URLImpl _url=new URLImpl(); 254 private FormImpl _form=new FormImpl(); 255 256 private URLForm urlForm=new UrlFormImpl(_form,_url); 257 private URL url; 258 private Form form; 259 260 261 private RequestImpl request=new RequestImpl(); 262 private CGIImplReadOnly cgiR=new CGIImplReadOnly(); 263 private CGIImpl cgiRW=new CGIImpl(); 264 private Argument argument=new ArgumentImpl(); 265 private static LocalNotSupportedScope localUnsupportedScope=LocalNotSupportedScope.getInstance(); 266 private Local local=localUnsupportedScope; 267 private Session session; 268 private Server server; 269 private Cluster cluster; 270 private CookieImpl cookie=new CookieImpl(); 271 private Client client; 272 private Application application; 273 274 private DebuggerPro debugger=new DebuggerImpl(); 275 private long requestTimeout=-1; 276 private short enablecfoutputonly=0; 277 private int outputState; 278 private String cfid; 279 private String cftoken; 280 281 private int id; 282 private int requestId; 283 284 285 private boolean psq; 286 private Locale locale; 287 private TimeZone timeZone; 288 289 // Pools 290 private ErrorPagePool errorPagePool=new ErrorPagePool(); 291 private TagHandlerPool tagHandlerPool; 292 private FTPPoolImpl ftpPool=new FTPPoolImpl(); 293 294 private Component activeComponent; 295 private UDF activeUDF; 296 private Collection.Key activeUDFCalledName; 297 //private ComponentScope componentScope=new ComponentScope(this); 298 299 private Credential remoteUser; 300 301 protected VariableUtilImpl variableUtil=new VariableUtilImpl(); 302 303 private PageException exception; 304 private PageSource base; 305 306 ApplicationContextPro applicationContext; 307 ApplicationContextPro defaultApplicationContext; 308 309 private ScopeFactory scopeFactory=new ScopeFactory(); 310 311 private Tag parentTag=null; 312 private Tag currentTag=null; 313 private Thread thread; 314 private long startTime; 315 private boolean isCFCRequest; 316 317 private DatasourceManagerImpl manager; 318 private Struct threads; 319 private boolean hasFamily=false; 320 //private CFMLFactoryImpl factory; 321 private PageContextImpl parent; 322 private Map<String,DatasourceConnection> transConns=new ConcurrentHashMap<String,DatasourceConnection>(); 323 private List<Statement> lazyStats; 324 private boolean fdEnabled; 325 private ExecutionLog execLog; 326 private boolean useSpecialMappings; 327 328 329 private ORMSession ormSession; 330 private boolean isChild; 331 private boolean gatewayContext; 332 private String serverPassword; 333 334 private PageException pe; 335 336 private Throwable requestTimeoutException; 337 338 private int appListenerType=AppListenerUtil.TYPE_ALL; 339 340 private boolean literalTimestampWithTSOffset; 341 342 public long sizeOf() { 343 344 return 345 SizeOf.size(pathList)+ 346 SizeOf.size(includePathList)+ 347 SizeOf.size(executionTime)+ 348 SizeOf.size(writer)+ 349 SizeOf.size(forceWriter)+ 350 SizeOf.size(bodyContentStack)+ 351 SizeOf.size(variables)+ 352 SizeOf.size(url)+ 353 SizeOf.size(form)+ 354 SizeOf.size(_url)+ 355 SizeOf.size(_form)+ 356 SizeOf.size(request)+ 357 358 SizeOf.size(argument)+ 359 SizeOf.size(local)+ 360 SizeOf.size(cookie)+ 361 SizeOf.size(debugger)+ 362 SizeOf.size(requestTimeout)+ 363 SizeOf.size(enablecfoutputonly)+ 364 SizeOf.size(outputState)+ 365 SizeOf.size(cfid)+ 366 SizeOf.size(cftoken)+ 367 SizeOf.size(id)+ 368 SizeOf.size(psq)+ 369 SizeOf.size(locale)+ 370 SizeOf.size(errorPagePool)+ 371 SizeOf.size(tagHandlerPool)+ 372 SizeOf.size(ftpPool)+ 373 SizeOf.size(activeComponent)+ 374 SizeOf.size(activeUDF)+ 375 SizeOf.size(remoteUser)+ 376 SizeOf.size(exception)+ 377 SizeOf.size(base)+ 378 SizeOf.size(applicationContext)+ 379 SizeOf.size(defaultApplicationContext)+ 380 SizeOf.size(parentTag)+ 381 SizeOf.size(currentTag)+ 382 SizeOf.size(startTime)+ 383 SizeOf.size(isCFCRequest)+ 384 SizeOf.size(transConns)+ 385 SizeOf.size(lazyStats)+ 386 SizeOf.size(serverPassword)+ 387 SizeOf.size(ormSession); 388 } 389 390 391 392 /** 393 * default Constructor 394 * @param scopeContext 395 * @param config Configuration of the CFML Container 396 * @param queryCache Query Cache Object 397 * @param id identity of the pageContext 398 * @param servlet 399 */ 400 public PageContextImpl(ScopeContext scopeContext, ConfigWebImpl config, int id,HttpServlet servlet) { 401 // must be first because is used after 402 tagHandlerPool=config.getTagHandlerPool(); 403 this.servlet=servlet; 404 this.id=id; 405 //this.factory=factory; 406 407 bodyContentStack=new BodyContentStack(); 408 devNull=bodyContentStack.getDevNullBodyContent(); 409 410 this.config=config; 411 manager=new DatasourceManagerImpl(config); 412 413 this.scopeContext=scopeContext; 414 undefined= 415 new UndefinedImpl(this,getScopeCascadingType()); 416 server=ScopeContext.getServerScope(this); 417 418 defaultApplicationContext=new ClassicApplicationContext(config,"",true,null); 419 420 } 421 422 @Override 423 public void initialize( 424 Servlet servlet, 425 ServletRequest req, 426 ServletResponse rsp, 427 String errorPageURL, 428 boolean needsSession, 429 int bufferSize, 430 boolean autoFlush) throws IOException, IllegalStateException, IllegalArgumentException { 431 initialize( 432 (HttpServlet)servlet, 433 (HttpServletRequest)req, 434 (HttpServletResponse)rsp, 435 errorPageURL, 436 needsSession, 437 bufferSize, 438 autoFlush,false); 439 } 440 441 442 public boolean isInitialized() { 443 return rsp!=null; 444 } 445 446 447 /** 448 * return if the PageContext is from a stopped thread, if so it should no longer be used! 449 * @return 450 */ 451 public Throwable getStopPosition() { 452 return requestTimeoutException; 453 } 454 public void stop(Throwable requestTimeoutException) { 455 this.requestTimeoutException=requestTimeoutException; 456 } 457 458 459 /** 460 * initialize a existing page context 461 * @param servlet 462 * @param req 463 * @param rsp 464 * @param errorPageURL 465 * @param needsSession 466 * @param bufferSize 467 * @param autoFlush 468 */ 469 public PageContextImpl initialize( 470 HttpServlet servlet, 471 HttpServletRequest req, 472 HttpServletResponse rsp, 473 String errorPageURL, 474 boolean needsSession, 475 int bufferSize, 476 boolean autoFlush, 477 boolean isChild) { 478 requestId=counter++; 479 rsp.setContentType("text/html; charset=UTF-8"); 480 this.isChild=isChild; 481 appListenerType=AppListenerUtil.TYPE_ALL; 482 //rsp.setHeader("Connection", "close"); 483 applicationContext=defaultApplicationContext; 484 485 startTime=System.currentTimeMillis(); 486 thread=Thread.currentThread(); 487 488 isCFCRequest = StringUtil.endsWithIgnoreCase(req.getServletPath(),"."+config.getCFCExtension()); 489 490 this.req=new HTTPServletRequestWrap(req); 491 this.rsp=rsp; 492 this.servlet=servlet; 493 494 // Writers 495 if(config.debugLogOutput()) { 496 CFMLWriter w = config.getCFMLWriter(this,req,rsp); 497 w.setAllowCompression(false); 498 DebugCFMLWriter dcw = new DebugCFMLWriter(w); 499 bodyContentStack.init(dcw); 500 debugger.setOutputLog(dcw); 501 } 502 else { 503 bodyContentStack.init(config.getCFMLWriter(this,req,rsp)); 504 } 505 506 507 writer=bodyContentStack.getWriter(); 508 forceWriter=writer; 509 510 // Scopes 511 server=ScopeContext.getServerScope(this); 512 if(hasFamily) { 513 variablesRoot=new VariablesImpl(); 514 variables=variablesRoot; 515 request=new RequestImpl(); 516 _url=new URLImpl(); 517 _form=new FormImpl(); 518 urlForm=new UrlFormImpl(_form,_url); 519 undefined= 520 new UndefinedImpl(this,getScopeCascadingType()); 521 522 hasFamily=false; 523 } 524 else if(variables==null) { 525 variablesRoot=new VariablesImpl(); 526 variables=variablesRoot; 527 } 528 request.initialize(this); 529 530 if(config.mergeFormAndURL()) { 531 url=urlForm; 532 form=urlForm; 533 } 534 else { 535 url=_url; 536 form=_form; 537 } 538 //url.initialize(this); 539 //form.initialize(this); 540 //undefined.initialize(this); 541 542 543 psq=config.getPSQL(); 544 545 fdEnabled=!config.allowRequestTimeout(); 546 547 if(config.getExecutionLogEnabled()) 548 this.execLog=config.getExecutionLogFactory().getInstance(this); 549 if(debugger!=null) 550 debugger.init(config); 551 552 undefined.initialize(this); 553 return this; 554 } 555 556 @Override 557 public void release() { 558 ConfigWebUtil.getCacheHandlerFactories(getConfig()).release(this); 559 560 if(config.getExecutionLogEnabled()){ 561 execLog.release(); 562 execLog=null; 563 } 564 565 if(config.debug()) { 566 if(!gatewayContext && !isChild) 567 config.getDebuggerPool().store(this, debugger); 568 debugger.reset(); 569 } 570 else ((DebuggerImpl)debugger).resetTraces(); // traces can alo be used when debugging is off 571 572 this.serverPassword=null; 573 574// boolean isChild=parent!=null; // isChild is defined in the class outside this method 575 parent=null; 576 // Attention have to be before close 577 if(client!=null){ 578 client.touchAfterRequest(this); 579 client=null; 580 } 581 if(session!=null){ 582 session.touchAfterRequest(this); 583 session=null; 584 } 585 586 // ORM 587 if(ormSession!=null){ 588 // flush orm session 589 try { 590 ORMEngine engine=ormSession.getEngine(); 591 ORMConfiguration config=engine.getConfiguration(this); 592 if(config==null || (config.flushAtRequestEnd() && config.autoManageSession())){ 593 ormSession.flushAll(this); 594 } 595 ormSession.closeAll(this); 596 } 597 catch (Throwable t) { 598 ExceptionUtil.rethrowIfNecessary(t); 599 //print.printST(t); 600 } 601 ormSession=null; 602 } 603 604 605 // Scopes 606 if(hasFamily) { 607 if(!isChild){ 608 req.disconnect(this); 609 } 610 611 close(); 612 thread=null; 613 base=null; 614 615 616 request=null; 617 _url=null; 618 _form=null; 619 urlForm=null; 620 undefined=null; 621 variables=null; 622 variablesRoot=null; 623 if(threads!=null && threads.size()>0) threads.clear(); 624 625 } 626 else { 627 close(); 628 thread=null; 629 base=null; 630 631 632 if(variables.isBind()) { 633 variables=null; 634 variablesRoot=null; 635 } 636 else { 637 variables=variablesRoot; 638 variables.release(this); 639 } 640 undefined.release(this); 641 urlForm.release(this); 642 request.release(); 643 } 644 cgiR.release(this); 645 cgiRW.release(this); 646 647 argument.release(this); 648 local=localUnsupportedScope; 649 650 cookie.release(); 651 //if(cluster!=null)cluster.release(); 652 653 //client=null; 654 //session=null; 655 656 657 658 659 application=null;// not needed at the moment -> application.releaseAfterRequest(); 660 applicationContext=null; 661 662 // Properties 663 requestTimeout=-1; 664 outputState=0; 665 cfid=null; 666 cftoken=null; 667 locale=null; 668 timeZone=null; 669 url=null; 670 form=null; 671 672 673 // Pools 674 errorPagePool.clear(); 675 676 // transaction connection 677 if(!transConns.isEmpty()){ 678 java.util.Iterator<DatasourceConnection> it = transConns.values().iterator(); 679 DatasourceConnectionPool pool = config.getDatasourceConnectionPool(); 680 while(it.hasNext()) { 681 pool.releaseDatasourceConnection(config,(it.next()),true); 682 } 683 transConns.clear(); 684 } 685 686 687 // lazy statements 688 if(lazyStats!=null && !lazyStats.isEmpty()){ 689 java.util.Iterator<Statement> it = lazyStats.iterator(); 690 while(it.hasNext()) { 691 DBUtil.closeEL(it.next()); 692 } 693 lazyStats.clear(); 694 lazyStats=null; 695 } 696 697 698 699 pathList.clear(); 700 includePathList.clear(); 701 executionTime=0; 702 703 bodyContentStack.release(); 704 705 706 707 //activeComponent=null; 708 remoteUser=null; 709 exception=null; 710 ftpPool.clear(); 711 parentTag=null; 712 currentTag=null; 713 714 // Req/Rsp 715 //if(req!=null) 716 req.clear(); 717 req=null; 718 rsp=null; 719 servlet=null; 720 721 // Writer 722 writer=null; 723 forceWriter=null; 724 if(pagesUsed.size()>0)pagesUsed.clear(); 725 726 activeComponent=null; 727 activeUDF=null; 728 729 730 gatewayContext=false; 731 732 manager.release(); 733 includeOnce.clear(); 734 pe=null; 735 736 literalTimestampWithTSOffset=false; 737 738 } 739 740 @Override 741 public void write(String str) throws IOException { 742 writer.write(str); 743 } 744 745 @Override 746 public void forceWrite(String str) throws IOException { 747 forceWriter.write(str); 748 } 749 750 @Override 751 public void writePSQ(Object o) throws IOException, PageException { 752 if(o instanceof Date || Decision.isDate(o, false)) { 753 writer.write(Caster.toString(o)); 754 } 755 else { 756 writer.write(psq?Caster.toString(o):StringUtil.replace(Caster.toString(o),"'","''",false)); 757 } 758 } 759 760 @Override 761 public void flush() { 762 try { 763 getOut().flush(); 764 } catch (IOException e) {} 765 } 766 767 @Override 768 public void close() { 769 IOUtil.closeEL(getOut()); 770 } 771 772 public PageSource getRelativePageSource(String relPath) { 773 SystemOut.print(config.getOutWriter(),"method getRelativePageSource is deprecated"); 774 if(StringUtil.startsWith(relPath,'/')) return PageSourceImpl.best(getPageSources(relPath)); 775 if(pathList.size()==0) return null; 776 return pathList.getLast().getRealPage(relPath); 777 } 778 779 public PageSource getRelativePageSourceExisting(String relPath) { 780 if(StringUtil.startsWith(relPath,'/')) return getPageSourceExisting(relPath); 781 if(pathList.size()==0) return null; 782 PageSource ps = pathList.getLast().getRealPage(relPath); 783 if(PageSourceImpl.pageExist(ps)) return ps; 784 return null; 785 } 786 787 /** 788 * 789 * @param relPath 790 * @param previous relative not to the caller, relative to the callers caller 791 * @return 792 */ 793 public PageSource getRelativePageSourceExisting(String relPath, boolean previous ) { 794 if(StringUtil.startsWith(relPath,'/')) return getPageSourceExisting(relPath); 795 if(pathList.size()==0) return null; 796 797 PageSource ps=null,tmp=null; 798 if(previous) { 799 boolean valid=false; 800 ps=pathList.getLast(); 801 for(int i=pathList.size()-2;i>=0;i--){ 802 tmp=pathList.get(i); 803 if(tmp!=ps) { 804 ps=tmp; 805 valid=true; 806 break; 807 } 808 } 809 if(!valid) return null; 810 } 811 else ps=pathList.getLast(); 812 813 ps = ps.getRealPage(relPath); 814 if(PageSourceImpl.pageExist(ps)) return ps; 815 return null; 816 } 817 818 public PageSource[] getRelativePageSources(String relPath) { 819 if(StringUtil.startsWith(relPath,'/')) return getPageSources(relPath); 820 if(pathList.size()==0) return null; 821 return new PageSource[]{ pathList.getLast().getRealPage(relPath)}; 822 } 823 824 public PageSource getPageSource(String relPath) { 825 SystemOut.print(config.getOutWriter(),"method getPageSource is deprecated"); 826 return PageSourceImpl.best(config.getPageSources(this,applicationContext.getMappings(),relPath,false,useSpecialMappings,true)); 827 } 828 829 public PageSource[] getPageSources(String relPath) { 830 return config.getPageSources(this,applicationContext.getMappings(),relPath,false,useSpecialMappings,true); 831 } 832 833 public PageSource getPageSourceExisting(String relPath) { 834 return config.getPageSourceExisting(this,applicationContext.getMappings(),relPath,false,useSpecialMappings,true,false); 835 } 836 837 public boolean useSpecialMappings(boolean useTagMappings) { 838 boolean b=this.useSpecialMappings; 839 this.useSpecialMappings=useTagMappings; 840 return b; 841 } 842 public boolean useSpecialMappings() { 843 return useSpecialMappings; 844 } 845 846 847 public Resource getPhysical(String relPath, boolean alsoDefaultMapping){ 848 return config.getPhysical(applicationContext.getMappings(),relPath, alsoDefaultMapping); 849 } 850 851 852 public PageSource toPageSource(Resource res, PageSource defaultValue){ 853 return config.toPageSource(applicationContext.getMappings(),res, defaultValue); 854 } 855 856 @Override 857 public void doInclude(String relPath) throws PageException { 858 doInclude(getRelativePageSources(relPath),false); 859 } 860 861 @Override 862 public void doInclude(String relPath, boolean runOnce) throws PageException { 863 doInclude(getRelativePageSources(relPath),runOnce); 864 } 865 866 public void doInclude(String relPath, boolean runOnce, Object cachedWithin) throws PageException { 867 if(cachedWithin==null) { 868 doInclude(relPath, runOnce); 869 } 870 871 // ignore call when runonce an it is not first call 872 PageSource[] sources = getRelativePageSources(relPath); 873 if(runOnce) { 874 Page currentPage = PageSourceImpl.loadPage(this, sources); 875 if(runOnce && includeOnce.contains(currentPage.getPageSource())) return; 876 } 877 878 // get cached data 879 String id=CacheHandlerFactory.createId(sources); 880 CacheHandler ch = ConfigWebUtil.getCacheHandlerFactories(getConfig()).include.getInstance(getConfig(), cachedWithin); 881 CacheItem ci=ch.get(this, id); 882 883 if(ci instanceof IncludeCacheItem) { 884 try { 885 write(((IncludeCacheItem)ci).getOutput()); 886 return; 887 } catch (IOException e) { 888 throw Caster.toPageException(e); 889 } 890 } 891 long start = System.nanoTime(); 892 893 BodyContent bc = pushBody(); 894 895 try { 896 doInclude(sources, runOnce); 897 String out = bc.getString(); 898 ch.set(this, id,cachedWithin,new IncludeCacheItem( 899 out 900 ,ArrayUtil.isEmpty(sources)?null:sources[0] 901 ,System.nanoTime()-start)); 902 return; 903 } 904 finally { 905 BodyContentUtil.flushAndPop(this,bc); 906 } 907 } 908 909 @Override 910 public void doInclude(PageSource source) throws PageException { 911 doInclude(new PageSource[]{source},false); 912 } 913 914 @Override 915 public void doInclude(PageSource[] sources, boolean runOnce) throws PageException { 916 // debug 917 if(!gatewayContext && config.debug()) { 918 final long currTime=executionTime; 919 long exeTime=0; 920 long time=System.nanoTime(); 921 922 Page currentPage = PageSourceImpl.loadPage(this, sources); 923 if(runOnce && includeOnce.contains(currentPage.getPageSource())) return; 924 DebugEntryTemplate debugEntry=debugger.getEntry(this,currentPage.getPageSource()); 925 try { 926 addPageSource(currentPage.getPageSource(),true); 927 debugEntry.updateFileLoadTime((System.nanoTime()-time)); 928 exeTime=System.nanoTime(); 929 930 currentPage.call(this); 931 } 932 catch(Throwable t){ 933 PageException pe = Caster.toPageException(t); 934 if(Abort.isAbort(pe)) { 935 if(Abort.isAbort(pe,Abort.SCOPE_REQUEST))throw pe; 936 } 937 else { 938 if(fdEnabled){ 939 FDSignal.signal(pe, false); 940 } 941 pe.addContext(currentPage.getPageSource(),-187,-187, null);// TODO was soll das 187 942 throw pe; 943 } 944 } 945 finally { 946 includeOnce.add(currentPage.getPageSource()); 947 long diff= ((System.nanoTime()-exeTime)-(executionTime-currTime)); 948 executionTime+=(System.nanoTime()-time); 949 debugEntry.updateExeTime(diff); 950 removeLastPageSource(true); 951 } 952 } 953 // no debug 954 else { 955 Page currentPage = PageSourceImpl.loadPage(this, sources); 956 if(runOnce && includeOnce.contains(currentPage.getPageSource())) return; 957 try { 958 addPageSource(currentPage.getPageSource(),true); 959 currentPage.call(this); 960 } 961 catch(Throwable t){ 962 PageException pe = Caster.toPageException(t); 963 if(Abort.isAbort(pe)) { 964 if(Abort.isAbort(pe,Abort.SCOPE_REQUEST))throw pe; 965 } 966 else { 967 pe.addContext(currentPage.getPageSource(),-187,-187, null); 968 throw pe; 969 } 970 } 971 finally { 972 includeOnce.add(currentPage.getPageSource()); 973 removeLastPageSource(true); 974 } 975 } 976 } 977 978 @Override 979 public Array getTemplatePath() throws PageException { 980 int len=includePathList.size(); 981 SVArray sva = new SVArray(); 982 PageSource ps; 983 for(int i=0;i<len;i++) { 984 ps=includePathList.get(i); 985 if(i==0) { 986 if(!ps.equals(getBasePageSource())) 987 sva.append(getBasePageSource().getResourceTranslated(this).getAbsolutePath()); 988 } 989 sva.append(ps.getResourceTranslated(this).getAbsolutePath()); 990 } 991 //sva.setPosition(sva.size()); 992 return sva; 993 } 994 995 public List<PageSource> getPageSourceList() { 996 return (List<PageSource>) pathList.clone(); 997 } 998 999 1000 1001 public PageSource getPageSource(int index) { 1002 return includePathList.get(index-1); 1003 } 1004 public synchronized void copyStateTo(PageContextImpl other) { 1005 1006 // cfid (we do this that way, otherwise we only have the same cfid if the current pc has defined cfid in cookie or url) 1007 getCFID(); 1008 other.cfid=cfid; 1009 other.cftoken=cftoken; 1010 1011 // private Debugger debugger=new DebuggerImpl(); 1012 other.requestTimeout=requestTimeout; 1013 other.locale=locale; 1014 other.timeZone=timeZone; 1015 other.fdEnabled=fdEnabled; 1016 other.useSpecialMappings=useSpecialMappings; 1017 other.serverPassword=serverPassword; 1018 1019 1020 hasFamily=true; 1021 other.hasFamily=true; 1022 other.parent=this; 1023 other.applicationContext=applicationContext; 1024 other.thread=Thread.currentThread(); 1025 other.startTime=System.currentTimeMillis(); 1026 other.isCFCRequest = isCFCRequest; 1027 1028 1029 1030 // path 1031 other.base=base; 1032 java.util.Iterator<PageSource> it = includePathList.iterator(); 1033 while(it.hasNext()) { 1034 other.includePathList.add(it.next()); 1035 } 1036 it = pathList.iterator(); 1037 while(it.hasNext()) { 1038 other.pathList.add(it.next()); 1039 } 1040 1041 1042 // scopes 1043 other.req=req; 1044 other.request=request; 1045 other.form=form; 1046 other.url=url; 1047 other.urlForm=urlForm; 1048 other._url=_url; 1049 other._form=_form; 1050 other.variables=variables; 1051 other.undefined=new UndefinedImpl(other,(short)other.undefined.getType()); 1052 1053 // writers 1054 other.bodyContentStack.init(config.getCFMLWriter(this,other.req,other.rsp)); 1055 //other.bodyContentStack.init(other.req,other.rsp,other.config.isSuppressWhitespace(),other.config.closeConnection(), other.config.isShowVersion(),config.contentLength(),config.allowCompression()); 1056 other.writer=other.bodyContentStack.getWriter(); 1057 other.forceWriter=other.writer; 1058 1059 other.psq=psq; 1060 other.gatewayContext=gatewayContext; 1061 1062 // thread 1063 if(threads!=null){ 1064 synchronized (threads) { 1065 1066 java.util.Iterator<Entry<Key, Object>> it2 = threads.entryIterator(); 1067 Entry<Key, Object> entry; 1068 while(it2.hasNext()) { 1069 entry = it2.next(); 1070 other.setThreadScope(entry.getKey(), (Threads)entry.getValue()); 1071 } 1072 } 1073 } 1074 1075 1076 // initialize stuff 1077 other.undefined.initialize(other); 1078 1079 1080 } 1081 1082 public int getCurrentLevel() { 1083 return includePathList.size()+1; 1084 } 1085 1086 /** 1087 * @return the current template PageSource 1088 */ 1089 public PageSource getCurrentPageSource() { 1090 if(pathList.isEmpty()) return null; 1091 return pathList.getLast(); 1092 } 1093 public PageSource getCurrentPageSource(PageSource defaultvalue) { 1094 if(pathList.isEmpty()) return defaultvalue; 1095 return pathList.getLast(); 1096 } 1097 1098 /** 1099 * @return the current template PageSource 1100 */ 1101 public PageSource getCurrentTemplatePageSource() { 1102 return includePathList.getLast(); 1103 } 1104 1105 /** 1106 * @return base template file 1107 */ 1108 public PageSource getBasePageSource() { 1109 return base; 1110 } 1111 1112 @Override 1113 public Resource getRootTemplateDirectory() { 1114 return config.getResource(ReqRspUtil.getRootPath(servlet.getServletContext())); 1115 } 1116 1117 @Override 1118 public Scope scope(int type) throws PageException { 1119 switch(type) { 1120 case Scope.SCOPE_UNDEFINED: return undefinedScope(); 1121 case Scope.SCOPE_URL: return urlScope(); 1122 case Scope.SCOPE_FORM: return formScope(); 1123 case Scope.SCOPE_VARIABLES: return variablesScope(); 1124 case Scope.SCOPE_REQUEST: return requestScope(); 1125 case Scope.SCOPE_CGI: return cgiScope(); 1126 case Scope.SCOPE_APPLICATION: return applicationScope(); 1127 case Scope.SCOPE_ARGUMENTS: return argumentsScope(); 1128 case Scope.SCOPE_SESSION: return sessionScope(); 1129 case Scope.SCOPE_SERVER: return serverScope(); 1130 case Scope.SCOPE_COOKIE: return cookieScope(); 1131 case Scope.SCOPE_CLIENT: return clientScope(); 1132 case Scope.SCOPE_LOCAL: 1133 case ScopeSupport.SCOPE_VAR: return localScope(); 1134 case Scope.SCOPE_CLUSTER:return clusterScope(); 1135 } 1136 return variables; 1137 } 1138 1139 public Scope scope(String strScope,Scope defaultValue) throws PageException { 1140 if(strScope==null)return defaultValue; 1141 strScope=strScope.toLowerCase().trim(); 1142 if("variables".equals(strScope)) return variablesScope(); 1143 if("url".equals(strScope)) return urlScope(); 1144 if("form".equals(strScope)) return formScope(); 1145 if("request".equals(strScope)) return requestScope(); 1146 if("cgi".equals(strScope)) return cgiScope(); 1147 if("application".equals(strScope)) return applicationScope(); 1148 if("arguments".equals(strScope)) return argumentsScope(); 1149 if("session".equals(strScope)) return sessionScope(); 1150 if("server".equals(strScope)) return serverScope(); 1151 if("cookie".equals(strScope)) return cookieScope(); 1152 if("client".equals(strScope)) return clientScope(); 1153 if("local".equals(strScope)) return localScope(); 1154 if("cluster".equals(strScope)) return clusterScope(); 1155 1156 return defaultValue; 1157 } 1158 1159 @Override 1160 public Undefined undefinedScope() { 1161 if(!undefined.isInitalized()) undefined.initialize(this); 1162 return undefined; 1163 } 1164 1165 /** 1166 * @return undefined scope, undefined scope is a placeholder for the scopecascading 1167 */ 1168 public Undefined us() { 1169 if(!undefined.isInitalized()) undefined.initialize(this); 1170 return undefined; 1171 } 1172 1173 @Override 1174 public Variables variablesScope() { return variables; } 1175 1176 @Override 1177 public URL urlScope() { 1178 if(!url.isInitalized())url.initialize(this); 1179 return url; 1180 } 1181 1182 @Override 1183 public Form formScope() { 1184 if(!form.isInitalized())form.initialize(this); 1185 return form; 1186 } 1187 1188 @Override 1189 public URLForm urlFormScope() { 1190 if(!urlForm.isInitalized())urlForm.initialize(this); 1191 return urlForm; 1192 } 1193 1194 @Override 1195 public Request requestScope() { return request; } 1196 1197 @Override 1198 public CGI cgiScope() { 1199 CGI cgi=applicationContext.getCGIScopeReadonly()?cgiR:cgiRW; 1200 if(!cgi.isInitalized())cgi.initialize(this); 1201 return cgi; 1202 } 1203 1204 @Override 1205 public Application applicationScope() throws PageException { 1206 if(application==null) { 1207 if(!applicationContext.hasName()) 1208 throw new ExpressionException("there is no application context defined for this application","you can define a application context with the tag "+lucee.runtime.config.Constants.CFAPP_NAME+"/"+lucee.runtime.config.Constants.APP_CFC); 1209 application=scopeContext.getApplicationScope(this,DUMMY_BOOL); 1210 } 1211 return application; 1212 } 1213 1214 @Override 1215 public Argument argumentsScope() { return argument; } 1216 1217 1218 @Override 1219 public Argument argumentsScope(boolean bind) { 1220 //Argument a=argumentsScope(); 1221 if(bind)argument.setBind(true); 1222 return argument; 1223 } 1224 1225 @Override 1226 public Local localScope() { 1227 //if(local==localUnsupportedScope) 1228 // throw new PageRuntimeException(new ExpressionException("Unsupported Context for Local Scope")); 1229 return local; 1230 } 1231 1232 @Override 1233 public Local localScope(boolean bind) { 1234 if(bind)local.setBind(true); 1235 //if(local==localUnsupportedScope) 1236 // throw new PageRuntimeException(new ExpressionException("Unsupported Context for Local Scope")); 1237 return local; 1238 } 1239 1240 1241 public Object localGet() throws PageException { 1242 return localGet(false); 1243 } 1244 1245 public Object localGet(boolean bind, Object defaultValue) { 1246 if(undefined.getCheckArguments()){ 1247 return localScope(bind); 1248 } 1249 return undefinedScope().get(KeyConstants._local,defaultValue); 1250 } 1251 1252 public Object localGet(boolean bind) throws PageException { 1253 // inside a local supported block 1254 if(undefined.getCheckArguments()){ 1255 return localScope(bind); 1256 } 1257 return undefinedScope().get(KeyConstants._local); 1258 } 1259 1260 public Object localTouch() throws PageException { 1261 return localTouch(false); 1262 } 1263 1264 public Object localTouch(boolean bind) throws PageException { 1265 // inside a local supported block 1266 if(undefined.getCheckArguments()){ 1267 return localScope(bind); 1268 } 1269 return touch(undefinedScope(), KeyConstants._local); 1270 //return undefinedScope().get(LOCAL); 1271 } 1272 1273 public Object thisGet() throws PageException { 1274 return thisTouch(); 1275 } 1276 1277 public Object thisTouch() throws PageException { 1278 // inside a component 1279 if(undefined.variablesScope() instanceof ComponentScope){ 1280 return ((ComponentScope)undefined.variablesScope()).getComponent(); 1281 } 1282 return undefinedScope().get(KeyConstants._THIS); 1283 } 1284 1285 public Object thisGet(Object defaultValue) { 1286 return thisTouch(defaultValue); 1287 } 1288 1289 public Object thisTouch(Object defaultValue) { 1290 // inside a component 1291 if(undefined.variablesScope() instanceof ComponentScope){ 1292 return ((ComponentScope)undefined.variablesScope()).getComponent(); 1293 } 1294 return undefinedScope().get(KeyConstants._THIS,defaultValue); 1295 } 1296 1297 1298 /** 1299 * @param local sets the current local scope 1300 * @param argument sets the current argument scope 1301 */ 1302 public void setFunctionScopes(Local local,Argument argument) { 1303 this.argument=argument; 1304 this.local=local; 1305 undefined.setFunctionScopes(local,argument); 1306 } 1307 1308 @Override 1309 public Session sessionScope() throws PageException { 1310 return sessionScope(true); 1311 } 1312 public Session sessionScope(boolean checkExpires) throws PageException { 1313 if(session==null) { 1314 checkSessionContext(); 1315 session=scopeContext.getSessionScope(this,DUMMY_BOOL); 1316 } 1317 return session; 1318 } 1319 1320 1321 public void invalidateUserScopes(boolean migrateSessionData,boolean migrateClientData) throws PageException { 1322 checkSessionContext(); 1323 scopeContext.invalidateUserScope(this, migrateSessionData, migrateClientData); 1324 } 1325 1326 private void checkSessionContext() throws ExpressionException { 1327 if(!applicationContext.hasName()) 1328 throw new ExpressionException("there is no session context defined for this application","you can define a session context with the tag "+Constants.CFAPP_NAME+"/"+Constants.APP_CFC); 1329 if(!applicationContext.isSetSessionManagement()) 1330 throw new ExpressionException("session scope is not enabled","you can enable session scope with tag "+Constants.CFAPP_NAME+"/"+Constants.APP_CFC); 1331 } 1332 1333 @Override 1334 public Server serverScope() { 1335 //if(!server.isInitalized()) server.initialize(this); 1336 return server; 1337 } 1338 1339 public void reset() { 1340 server=ScopeContext.getServerScope(this); 1341 } 1342 1343 @Override 1344 public Cluster clusterScope() throws PageException { 1345 return clusterScope(true); 1346 } 1347 1348 public Cluster clusterScope(boolean create) throws PageException { 1349 if(cluster==null && create) { 1350 cluster=ScopeContext.getClusterScope(config,create); 1351 //cluster.initialize(this); 1352 } 1353 //else if(!cluster.isInitalized()) cluster.initialize(this); 1354 return cluster; 1355 } 1356 1357 @Override 1358 public Cookie cookieScope() { 1359 if(!cookie.isInitalized()) cookie.initialize(this); 1360 return cookie; 1361 } 1362 1363 @Override 1364 public Client clientScope() throws PageException { 1365 if(client==null) { 1366 if(!applicationContext.hasName()) 1367 throw new ExpressionException("there is no client context defined for this application", 1368 "you can define a client context with the tag "+Constants.CFAPP_NAME+"/"+Constants.APP_CFC); 1369 if(!applicationContext.isSetClientManagement()) 1370 throw new ExpressionException("client scope is not enabled", 1371 "you can enable client scope with tag "+Constants.CFAPP_NAME+"/"+Constants.APP_CFC); 1372 1373 client= scopeContext.getClientScope(this); 1374 } 1375 return client; 1376 } 1377 1378 public Client clientScopeEL() { 1379 if(client==null) { 1380 if(applicationContext==null || !applicationContext.hasName()) return null; 1381 if(!applicationContext.isSetClientManagement()) return null; 1382 client= scopeContext.getClientScopeEL(this); 1383 } 1384 return client; 1385 } 1386 1387 @Override 1388 public Object set(Object coll, String key, Object value) throws PageException { 1389 return variableUtil.set(this,coll,key,value); 1390 } 1391 1392 public Object set(Object coll, Collection.Key key, Object value) throws PageException { 1393 return variableUtil.set(this,coll,key,value); 1394 } 1395 1396 @Override 1397 public Object touch(Object coll, String key) throws PageException { 1398 Object o=getCollection(coll,key,null); 1399 if(o!=null) return o; 1400 return set(coll,key,new StructImpl()); 1401 } 1402 1403 @Override 1404 public Object touch(Object coll, Collection.Key key) throws PageException { 1405 Object o=getCollection(coll,key,null); 1406 if(o!=null) return o; 1407 return set(coll,key,new StructImpl()); 1408 } 1409 1410 /*private Object _touch(Scope scope, String key) throws PageException { 1411 Object o=scope.get(key,null); 1412 if(o!=null) return o; 1413 return scope.set(key, new StructImpl()); 1414 }*/ 1415 1416 1417 1418 1419 1420 @Override 1421 public Object getCollection(Object coll, String key) throws PageException { 1422 return variableUtil.getCollection(this,coll,key); 1423 } 1424 1425 @Override 1426 public Object getCollection(Object coll, Collection.Key key) throws PageException { 1427 return variableUtil.getCollection(this,coll,key); 1428 } 1429 1430 @Override 1431 public Object getCollection(Object coll, String key, Object defaultValue) { 1432 return variableUtil.getCollection(this,coll,key,defaultValue); 1433 } 1434 1435 @Override 1436 public Object getCollection(Object coll, Collection.Key key, Object defaultValue) { 1437 return variableUtil.getCollection(this,coll,key,defaultValue); 1438 } 1439 1440 @Override 1441 public Object get(Object coll, String key) throws PageException { 1442 return variableUtil.get(this,coll,key); 1443 } 1444 1445 @Override 1446 public Object get(Object coll, Collection.Key key) throws PageException { 1447 return variableUtil.get(this,coll,key); 1448 } 1449 1450 @Override 1451 public Reference getReference(Object coll, String key) throws PageException { 1452 return new VariableReference(coll,key); 1453 } 1454 1455 public Reference getReference(Object coll, Collection.Key key) throws PageException { 1456 return new VariableReference(coll,key); 1457 } 1458 1459 @Override 1460 public Object get(Object coll, String key, Object defaultValue) { 1461 return variableUtil.get(this,coll,key, defaultValue); 1462 } 1463 1464 @Override 1465 public Object get(Object coll, Collection.Key key, Object defaultValue) { 1466 return variableUtil.get(this,coll,key, defaultValue); 1467 } 1468 1469 @Override 1470 public Object setVariable(String var, Object value) throws PageException { 1471 //return new CFMLExprInterpreter().interpretReference(this,new ParserString(var)).set(value); 1472 return VariableInterpreter.setVariable(this,var,value); 1473 } 1474 1475 @Override 1476 public Object getVariable(String var) throws PageException { 1477 return VariableInterpreter.getVariable(this,var); 1478 } 1479 1480 1481 public void param(String type, String name, Object defaultValue,String regex) throws PageException { 1482 param(type, name, defaultValue,Double.NaN,Double.NaN,regex,-1); 1483 } 1484 public void param(String type, String name, Object defaultValue,double min, double max) throws PageException { 1485 param(type, name, defaultValue,min,max,null,-1); 1486 } 1487 1488 public void param(String type, String name, Object defaultValue,int maxLength) throws PageException { 1489 param(type, name, defaultValue,Double.NaN,Double.NaN,null,maxLength); 1490 } 1491 1492 public void param(String type, String name, Object defaultValue) throws PageException { 1493 param(type, name, defaultValue,Double.NaN,Double.NaN,null,-1); 1494 } 1495 1496 private void param(String type, String name, Object defaultValue, double min,double max, String strPattern, int maxLength) throws PageException { 1497 1498 // check attributes type 1499 if(type==null)type="any"; 1500 else type=type.trim().toLowerCase(); 1501 1502 // check attributes name 1503 if(StringUtil.isEmpty(name)) 1504 throw new ExpressionException("The attribute name is required"); 1505 1506 Object value=null; 1507 boolean isNew=false; 1508 1509 // get value 1510 value=VariableInterpreter.getVariableEL(this,name,NullSupportHelper.NULL()); 1511 if(NullSupportHelper.NULL()==value) { 1512 if(defaultValue==null) 1513 throw new ExpressionException("The required parameter ["+name+"] was not provided."); 1514 value=defaultValue; 1515 isNew=true; 1516 } 1517 1518 // cast and set value 1519 if(!"any".equals(type)) { 1520 // range 1521 if("range".equals(type)) { 1522 boolean hasMin=Decision.isValid(min); 1523 boolean hasMax=Decision.isValid(max); 1524 double number = Caster.toDoubleValue(value); 1525 1526 if(!hasMin && !hasMax) 1527 throw new ExpressionException("you need to define one of the following attributes [min,max], when type is set to [range]"); 1528 1529 if(hasMin && number<min) 1530 throw new ExpressionException("The number ["+Caster.toString(number)+"] is to small, the number must be at least ["+Caster.toString(min)+"]"); 1531 1532 if(hasMax && number>max) 1533 throw new ExpressionException("The number ["+Caster.toString(number)+"] is to big, the number cannot be bigger than ["+Caster.toString(max)+"]"); 1534 1535 setVariable(name,Caster.toDouble(number)); 1536 } 1537 // regex 1538 else if("regex".equals(type) || "regular_expression".equals(type)) { 1539 String str=Caster.toString(value); 1540 1541 if(strPattern==null) throw new ExpressionException("Missing attribute [pattern]"); 1542 1543 try { 1544 Pattern pattern = new Perl5Compiler().compile(strPattern, Perl5Compiler.DEFAULT_MASK); 1545 PatternMatcherInput input = new PatternMatcherInput(str); 1546 if( !new Perl5Matcher().matches(input, pattern)) 1547 throw new ExpressionException("The value ["+str+"] doesn't match the provided pattern ["+strPattern+"]"); 1548 1549 } catch (MalformedPatternException e) { 1550 throw new ExpressionException("The provided pattern ["+strPattern+"] is invalid",e.getMessage()); 1551 } 1552 setVariable(name,str); 1553 } 1554 else if ( type.equals( "int" ) || type.equals( "integer" ) ) { 1555 1556 if ( !Decision.isInteger( value ) ) 1557 throw new ExpressionException( "The value [" + value + "] is not a valid integer" ); 1558 1559 setVariable( name, value ); 1560 } 1561 else { 1562 if(!Decision.isCastableTo(type,value,true,true,maxLength)) { 1563 if(maxLength>-1 && ("email".equalsIgnoreCase(type) || "url".equalsIgnoreCase(type) || "string".equalsIgnoreCase(type))) { 1564 StringBuilder msg=new StringBuilder(CasterException.createMessage(value, type)); 1565 msg.append(" with a maximum length of "+maxLength+" characters"); 1566 throw new CasterException(msg.toString()); 1567 } 1568 throw new CasterException(value,type); 1569 } 1570 1571 setVariable(name,value); 1572 //REALCAST setVariable(name,Caster.castTo(this,type,value,true)); 1573 } 1574 } 1575 else if(isNew) setVariable(name,value); 1576 } 1577 1578 1579 @Override 1580 public Object removeVariable(String var) throws PageException { 1581 return VariableInterpreter.removeVariable(this,var); 1582 } 1583 1584 /** 1585 * a variable reference, references to variable, to modifed it, with global effect. 1586 * @param var variable name to get 1587 * @return return a variable reference by string syntax ("scopename.key.key" -> "url.name") 1588 * @throws PageException 1589 */ 1590 public VariableReference getVariableReference(String var) throws PageException { 1591 return VariableInterpreter.getVariableReference(this,var); 1592 } 1593 1594 @Override 1595 public Object getFunction(Object coll, String key, Object[] args) throws PageException { 1596 return variableUtil.callFunctionWithoutNamedValues(this,coll,key,args); 1597 } 1598 1599 @Override 1600 public Object getFunction(Object coll, Key key, Object[] args) throws PageException { 1601 return variableUtil.callFunctionWithoutNamedValues(this,coll,key,args); 1602 } 1603 1604 @Override 1605 public Object getFunctionWithNamedValues(Object coll, String key, Object[] args) throws PageException { 1606 return variableUtil.callFunctionWithNamedValues(this,coll,key,args); 1607 } 1608 1609 @Override 1610 public Object getFunctionWithNamedValues(Object coll, Key key, Object[] args) throws PageException { 1611 return variableUtil.callFunctionWithNamedValues(this,coll,key,args); 1612 } 1613 1614 @Override 1615 public ConfigWeb getConfig() { 1616 return config; 1617 } 1618 1619 @Override 1620 public Iterator getIterator(String key) throws PageException { 1621 Object o=VariableInterpreter.getVariable(this,key); 1622 if(o instanceof Iterator) return (Iterator) o; 1623 throw new ExpressionException("["+key+"] is not a iterator object"); 1624 } 1625 1626 @Override 1627 public Query getQuery(String key) throws PageException { 1628 Object value=VariableInterpreter.getVariable(this,key); 1629 if(Decision.isQuery(value)) return Caster.toQuery(value); 1630 throw new CasterException(value,Query.class);///("["+key+"] is not a query object, object is from type "); 1631 } 1632 1633 @Override 1634 public Query getQuery(Object value) throws PageException { 1635 if(Decision.isQuery(value)) return Caster.toQuery(value); 1636 value=VariableInterpreter.getVariable(this,Caster.toString(value)); 1637 if(Decision.isQuery(value)) return Caster.toQuery(value); 1638 throw new CasterException(value,Query.class); 1639 } 1640 1641 @Override 1642 public void setAttribute(String name, Object value) { 1643 try { 1644 if(value==null)removeVariable(name); 1645 else setVariable(name,value); 1646 } catch (PageException e) {} 1647 } 1648 1649 @Override 1650 public void setAttribute(String name, Object value, int scope) { 1651 switch(scope){ 1652 case javax.servlet.jsp.PageContext.APPLICATION_SCOPE: 1653 if(value==null) getServletContext().removeAttribute(name); 1654 else getServletContext().setAttribute(name, value); 1655 break; 1656 case javax.servlet.jsp.PageContext.PAGE_SCOPE: 1657 setAttribute(name, value); 1658 break; 1659 case javax.servlet.jsp.PageContext.REQUEST_SCOPE: 1660 if(value==null) req.removeAttribute(name); 1661 else setAttribute(name, value); 1662 break; 1663 case javax.servlet.jsp.PageContext.SESSION_SCOPE: 1664 HttpSession s = req.getSession(true); 1665 if(value==null)s.removeAttribute(name); 1666 else s.setAttribute(name, value); 1667 break; 1668 } 1669 } 1670 1671 @Override 1672 public Object getAttribute(String name) { 1673 try { 1674 return getVariable(name); 1675 } catch (PageException e) { 1676 return null; 1677 } 1678 } 1679 1680 @Override 1681 public Object getAttribute(String name, int scope) { 1682 switch(scope){ 1683 case javax.servlet.jsp.PageContext.APPLICATION_SCOPE: 1684 return getServletContext().getAttribute(name); 1685 case javax.servlet.jsp.PageContext.PAGE_SCOPE: 1686 return getAttribute(name); 1687 case javax.servlet.jsp.PageContext.REQUEST_SCOPE: 1688 return req.getAttribute(name); 1689 case javax.servlet.jsp.PageContext.SESSION_SCOPE: 1690 HttpSession s = req.getSession(); 1691 if(s!=null)return s.getAttribute(name); 1692 break; 1693 } 1694 return null; 1695 } 1696 1697 @Override 1698 public Object findAttribute(String name) { 1699 // page 1700 Object value=getAttribute(name); 1701 if(value!=null) return value; 1702 // request 1703 value=req.getAttribute(name); 1704 if(value!=null) return value; 1705 // session 1706 HttpSession s = req.getSession(); 1707 value=s!=null?s.getAttribute(name):null; 1708 if(value!=null) return value; 1709 // application 1710 value=getServletContext().getAttribute(name); 1711 if(value!=null) return value; 1712 1713 1714 return null; 1715 } 1716 1717 @Override 1718 public void removeAttribute(String name) { 1719 setAttribute(name, null); 1720 } 1721 1722 @Override 1723 public void removeAttribute(String name, int scope) { 1724 setAttribute(name, null,scope); 1725 } 1726 1727 @Override 1728 public int getAttributesScope(String name) { 1729 // page 1730 if(getAttribute(name)!=null) return PageContext.PAGE_SCOPE; 1731 // request 1732 if(req.getAttribute(name) != null) return PageContext.REQUEST_SCOPE; 1733 // session 1734 HttpSession s = req.getSession(); 1735 if(s!=null && s.getAttribute(name) != null) return PageContext.SESSION_SCOPE; 1736 // application 1737 if(getServletContext().getAttribute(name)!=null) return PageContext.APPLICATION_SCOPE; 1738 1739 return 0; 1740 } 1741 1742 @Override 1743 public Enumeration getAttributeNamesInScope(int scope) { 1744 1745 switch(scope){ 1746 case javax.servlet.jsp.PageContext.APPLICATION_SCOPE: 1747 return getServletContext().getAttributeNames(); 1748 case javax.servlet.jsp.PageContext.PAGE_SCOPE: 1749 return ItAsEnum.toStringEnumeration(variablesScope().keyIterator()); 1750 case javax.servlet.jsp.PageContext.REQUEST_SCOPE: 1751 return req.getAttributeNames(); 1752 case javax.servlet.jsp.PageContext.SESSION_SCOPE: 1753 return req.getSession(true).getAttributeNames(); 1754 } 1755 return null; 1756 } 1757 1758 @Override 1759 public JspWriter getOut() { 1760 return forceWriter; 1761 } 1762 1763 @Override 1764 public HttpSession getSession() { 1765 return getHttpServletRequest().getSession(); 1766 } 1767 1768 @Override 1769 public Object getPage() { 1770 return variablesScope(); 1771 } 1772 1773 @Override 1774 public ServletRequest getRequest() { 1775 return getHttpServletRequest(); 1776 } 1777 1778 @Override 1779 public HttpServletRequest getHttpServletRequest() { 1780 return req; 1781 } 1782 1783 @Override 1784 public ServletResponse getResponse() { 1785 return rsp; 1786 } 1787 1788 @Override 1789 public HttpServletResponse getHttpServletResponse() { 1790 return rsp; 1791 } 1792 1793 public OutputStream getResponseStream() throws IOException { 1794 return getRootOut().getResponseStream(); 1795 } 1796 1797 @Override 1798 public Exception getException() { 1799 // TODO impl 1800 return exception; 1801 } 1802 1803 @Override 1804 public ServletConfig getServletConfig() { 1805 return config; 1806 } 1807 1808 @Override 1809 public ServletContext getServletContext() { 1810 return servlet.getServletContext(); 1811 } 1812 1813 /*public static void main(String[] args) { 1814 repl(" susi #error.susi# sorglos","susi", "Susanne"); 1815 repl(" susi #error.Susi# sorglos","susi", "Susanne"); 1816 }*/ 1817 private static String repl(String haystack, String needle, String replacement) { 1818 //print.o("------------"); 1819 //print.o(haystack); 1820 //print.o(needle); 1821 StringBuilder regex=new StringBuilder("#[\\s]*error[\\s]*\\.[\\s]*"); 1822 1823 char[] carr = needle.toCharArray(); 1824 for(int i=0;i<carr.length;i++){ 1825 regex.append("["); 1826 regex.append(Character.toLowerCase(carr[i])); 1827 regex.append(Character.toUpperCase(carr[i])); 1828 regex.append("]"); 1829 } 1830 1831 1832 regex.append("[\\s]*#"); 1833 //print.o(regex); 1834 1835 1836 haystack=haystack.replaceAll(regex.toString(), replacement); 1837 //print.o(haystack); 1838 return haystack; 1839 } 1840 1841 1842 @Override 1843 public void handlePageException(PageException pe) { 1844 if(!Abort.isSilentAbort(pe)) { 1845 if(requestTimeoutException!=null) 1846 pe=Caster.toPageException(requestTimeoutException); 1847 1848 1849 Charset cs = ReqRspUtil.getCharacterEncoding(this,rsp); 1850 if(cs==null) { 1851 rsp.setContentType("text/html"); 1852 } 1853 else { 1854 rsp.setContentType("text/html; charset=" + cs.name()); 1855 } 1856 if(pe instanceof PageExceptionImpl && ((PageExceptionImpl)pe).getExposeMessage()) 1857 rsp.setHeader("exception-message", StringUtil.emptyIfNull(pe.getMessage()).replace('\n', ' ')); 1858 //rsp.setHeader("exception-detail", pe.getDetail()); 1859 1860 int statusCode=getStatusCode(pe); 1861 1862 if(getConfig().getErrorStatusCode())rsp.setStatus(statusCode); 1863 1864 ErrorPage ep=errorPagePool.getErrorPage(pe,ErrorPageImpl.TYPE_EXCEPTION); 1865 1866 //ExceptionHandler.printStackTrace(this,pe); 1867 ExceptionHandler.log(getConfig(),pe); 1868 1869 // error page exception 1870 if(ep!=null) { 1871 try { 1872 Struct sct=pe.getErrorBlock(this,ep); 1873 variablesScope().setEL(KeyConstants._error,sct); 1874 variablesScope().setEL(KeyConstants._cferror,sct); 1875 1876 doInclude(ep.getTemplate()); 1877 return; 1878 } catch (Throwable t) { 1879 ExceptionUtil.rethrowIfNecessary(t); 1880 if(Abort.isSilentAbort(t)) return; 1881 pe=Caster.toPageException(t); 1882 } 1883 } 1884 1885 // error page request 1886 ep=errorPagePool.getErrorPage(pe,ErrorPageImpl.TYPE_REQUEST); 1887 if(ep!=null) { 1888 PageSource ps = ep.getTemplate(); 1889 if(ps.physcalExists()){ 1890 Resource res = ps.getResource(); 1891 try { 1892 String content = IOUtil.toString(res, getConfig().getTemplateCharset()); 1893 Struct sct=pe.getErrorBlock(this,ep); 1894 java.util.Iterator<Entry<Key, Object>> it = sct.entryIterator(); 1895 Entry<Key, Object> e; 1896 String v; 1897 while(it.hasNext()){ 1898 e = it.next(); 1899 v=Caster.toString(e.getValue(),null); 1900 if(v!=null)content=repl(content, e.getKey().getString(), v); 1901 } 1902 1903 write(content); 1904 return; 1905 } catch (Throwable t) { 1906 pe=Caster.toPageException(t); 1907 } 1908 } 1909 else pe=new ApplicationException("The error page template for type request only works if the actual source file also exists. If the exception file is in an Lucee archive (lco), you need to use type exception instead."); 1910 } 1911 1912 try { 1913 1914 String template=getConfig().getErrorTemplate(statusCode); 1915 if(!StringUtil.isEmpty(template)) { 1916 try { 1917 Struct catchBlock=pe.getCatchBlock(getConfig()); 1918 variablesScope().setEL(KeyConstants._cfcatch,catchBlock); 1919 variablesScope().setEL(KeyConstants._catch,catchBlock); 1920 doInclude(template); 1921 return; 1922 } 1923 catch (PageException e) { 1924 pe=e; 1925 } 1926 } 1927 if(!Abort.isSilentAbort(pe))forceWrite(getConfig().getDefaultDumpWriter(DumpWriter.DEFAULT_RICH).toString(this,pe.toDumpData(this, 9999,DumpUtil.toDumpProperties()),true)); 1928 } 1929 catch (Exception e) {} 1930 } 1931 } 1932 1933 private int getStatusCode(PageException pe) { 1934 int statusCode=500; 1935 int maxDeepFor404=0; 1936 if(pe instanceof ModernAppListenerException){ 1937 pe=((ModernAppListenerException)pe).getPageException(); 1938 maxDeepFor404=1; 1939 } 1940 else if(pe instanceof PageExceptionBox) 1941 pe=((PageExceptionBox)pe).getPageException(); 1942 1943 if(pe instanceof MissingIncludeException) { 1944 MissingIncludeException mie=(MissingIncludeException) pe; 1945 if(mie.getPageDeep()<=maxDeepFor404) statusCode=404; 1946 } 1947 1948 // TODO Auto-generated method stub 1949 return statusCode; 1950 } 1951 1952 1953 @Override 1954 public void handlePageException(Exception e) { 1955 // DO NOT rethrow ThreadDeath 1956 handlePageException(Caster.toPageException(e)); 1957 } 1958 1959 @Override 1960 public void handlePageException(Throwable t) { 1961 // DO NOT rethrow ThreadDeath 1962 handlePageException(Caster.toPageException(t)); 1963 } 1964 1965 @Override 1966 public void setHeader(String name, String value) { 1967 rsp.setHeader(name,value); 1968 } 1969 1970 @Override 1971 public BodyContent pushBody() { 1972 forceWriter=bodyContentStack.push(); 1973 if(enablecfoutputonly>0 && outputState==0) { 1974 writer=devNull; 1975 } 1976 else writer=forceWriter; 1977 return (BodyContent)forceWriter; 1978 } 1979 1980 @Override 1981 public JspWriter popBody() { 1982 forceWriter=bodyContentStack.pop(); 1983 if(enablecfoutputonly>0 && outputState==0) { 1984 writer=devNull; 1985 } 1986 else writer=forceWriter; 1987 return forceWriter; 1988 } 1989 1990 @Override 1991 public void outputStart() { 1992 outputState++; 1993 if(enablecfoutputonly>0 && outputState==1)writer=forceWriter; 1994 //if(enablecfoutputonly && outputState>0) unsetDevNull(); 1995 } 1996 1997 @Override 1998 public void outputEnd() { 1999 outputState--; 2000 if(enablecfoutputonly>0 && outputState==0)writer=devNull; 2001 } 2002 2003 @Override 2004 public void setCFOutputOnly(boolean boolEnablecfoutputonly) { 2005 if(boolEnablecfoutputonly)this.enablecfoutputonly++; 2006 else if(this.enablecfoutputonly>0)this.enablecfoutputonly--; 2007 setCFOutputOnly(enablecfoutputonly); 2008 //if(!boolEnablecfoutputonly)setCFOutputOnly(enablecfoutputonly=0); 2009 } 2010 2011 @Override 2012 public void setCFOutputOnly(short enablecfoutputonly) { 2013 this.enablecfoutputonly=enablecfoutputonly; 2014 if(enablecfoutputonly>0) { 2015 if(outputState==0) writer=devNull; 2016 } 2017 else { 2018 writer=forceWriter; 2019 } 2020 } 2021 2022 @Override 2023 public boolean setSilent() { 2024 boolean before=bodyContentStack.getDevNull(); 2025 bodyContentStack.setDevNull(true); 2026 2027 forceWriter = bodyContentStack.getWriter(); 2028 writer=forceWriter; 2029 return before; 2030 } 2031 2032 @Override 2033 public boolean unsetSilent() { 2034 boolean before=bodyContentStack.getDevNull(); 2035 bodyContentStack.setDevNull(false); 2036 2037 forceWriter = bodyContentStack.getWriter(); 2038 if(enablecfoutputonly>0 && outputState==0) { 2039 writer=devNull; 2040 } 2041 else writer=forceWriter; 2042 return before; 2043 } 2044 2045 2046 @Override 2047 public Debugger getDebugger() { 2048 return debugger; 2049 } 2050 2051 @Override 2052 public void executeRest(String relPath, boolean throwExcpetion) throws PageException { 2053 ApplicationListener listener=null;//config.get ApplicationListener(); 2054 try{ 2055 String pathInfo = req.getPathInfo(); 2056 2057 // charset 2058 try{ 2059 String charset=HTTPUtil.splitMimeTypeAndCharset(req.getContentType(),new String[]{"",""})[1]; 2060 if(StringUtil.isEmpty(charset))charset=getWebCharset().name(); 2061 java.net.URL reqURL = new java.net.URL(req.getRequestURL().toString()); 2062 String path=ReqRspUtil.decode(reqURL.getPath(),charset,true); 2063 String srvPath=req.getServletPath(); 2064 if(path.startsWith(srvPath)) { 2065 pathInfo=path.substring(srvPath.length()); 2066 } 2067 } 2068 catch (Exception e){} 2069 2070 2071 // Service mapping 2072 if(StringUtil.isEmpty(pathInfo) || pathInfo.equals("/")) {// ToDo 2073 // list available services (if enabled in admin) 2074 if(config.getRestList()) { 2075 try { 2076 HttpServletRequest _req = getHttpServletRequest(); 2077 write("Available sevice mappings are:<ul>"); 2078 lucee.runtime.rest.Mapping[] mappings = config.getRestMappings(); 2079 lucee.runtime.rest.Mapping _mapping; 2080 String path; 2081 for(int i=0;i<mappings.length;i++){ 2082 _mapping=mappings[i]; 2083 Resource p = _mapping.getPhysical(); 2084 path=_req.getContextPath()+ReqRspUtil.getScriptName(this,_req)+_mapping.getVirtual(); 2085 write("<li "+(p==null || !p.isDirectory()?" style=\"color:red\"":"")+">"+path+"</li>"); 2086 2087 2088 } 2089 write("</ul>"); 2090 2091 } catch (IOException e) { 2092 throw Caster.toPageException(e); 2093 } 2094 } 2095 else 2096 RestUtil.setStatus(this, 404, null); 2097 return; 2098 } 2099 2100 // check for matrix 2101 int index; 2102 String entry; 2103 Struct matrix=new StructImpl(); 2104 while((index=pathInfo.lastIndexOf(';'))!=-1){ 2105 entry=pathInfo.substring(index+1); 2106 pathInfo=pathInfo.substring(0,index); 2107 if(StringUtil.isEmpty(entry,true)) continue; 2108 2109 index=entry.indexOf('='); 2110 if(index!=-1)matrix.setEL(entry.substring(0,index).trim(), entry.substring(index+1).trim()); 2111 else matrix.setEL(entry.trim(), ""); 2112 } 2113 2114 // get accept 2115 List<MimeType> accept = ReqRspUtil.getAccept(this); 2116 MimeType contentType = ReqRspUtil.getContentType(this); 2117 2118 // check for format extension 2119 //int format = getApplicationContext().getRestSettings().getReturnFormat(); 2120 int format; 2121 boolean hasFormatExtension=false; 2122 if(StringUtil.endsWithIgnoreCase(pathInfo, ".json")) { 2123 pathInfo=pathInfo.substring(0,pathInfo.length()-5); 2124 format = UDF.RETURN_FORMAT_JSON; 2125 accept.clear(); 2126 accept.add(MimeType.APPLICATION_JSON); 2127 hasFormatExtension=true; 2128 } 2129 else if(StringUtil.endsWithIgnoreCase(pathInfo, ".wddx")) { 2130 pathInfo=pathInfo.substring(0,pathInfo.length()-5); 2131 format = UDF.RETURN_FORMAT_WDDX; 2132 accept.clear(); 2133 accept.add(MimeType.APPLICATION_WDDX); 2134 hasFormatExtension=true; 2135 } 2136 else if(StringUtil.endsWithIgnoreCase(pathInfo, ".cfml")) { 2137 pathInfo=pathInfo.substring(0,pathInfo.length()-5); 2138 format = UDF.RETURN_FORMAT_SERIALIZE; 2139 accept.clear(); 2140 accept.add(MimeType.APPLICATION_CFML); 2141 hasFormatExtension=true; 2142 } 2143 else if(StringUtil.endsWithIgnoreCase(pathInfo, ".serialize")) { 2144 pathInfo=pathInfo.substring(0,pathInfo.length()-10); 2145 format = UDF.RETURN_FORMAT_SERIALIZE; 2146 accept.clear(); 2147 accept.add(MimeType.APPLICATION_CFML); 2148 hasFormatExtension=true; 2149 } 2150 else if(StringUtil.endsWithIgnoreCase(pathInfo, ".xml")) { 2151 pathInfo=pathInfo.substring(0,pathInfo.length()-4); 2152 format = UDF.RETURN_FORMAT_XML; 2153 accept.clear(); 2154 accept.add(MimeType.APPLICATION_XML); 2155 hasFormatExtension=true; 2156 } 2157 else if(StringUtil.endsWithIgnoreCase(pathInfo, ".java")) { 2158 pathInfo=pathInfo.substring(0,pathInfo.length()-5); 2159 format = UDFPlus.RETURN_FORMAT_JAVA; 2160 accept.clear(); 2161 accept.add(MimeType.APPLICATION_JAVA); 2162 hasFormatExtension=true; 2163 } 2164 else { 2165 format = getApplicationContext().getRestSettings().getReturnFormat(); 2166 //MimeType mt=MimeType.toMimetype(format); 2167 //if(mt!=null)accept.add(mt); 2168 } 2169 2170 if(accept.size()==0) accept.add(MimeType.ALL); 2171 2172 // loop all mappings 2173 //lucee.runtime.rest.Result result = null;//config.getRestSource(pathInfo, null); 2174 RestRequestListener rl=null; 2175 lucee.runtime.rest.Mapping[] restMappings = config.getRestMappings(); 2176 lucee.runtime.rest.Mapping m,mapping=null,defaultMapping=null; 2177 //String callerPath=null; 2178 if(restMappings!=null)for(int i=0;i<restMappings.length;i++) { 2179 m = restMappings[i]; 2180 if(m.isDefault())defaultMapping=m; 2181 if(pathInfo.startsWith(m.getVirtualWithSlash(),0) && m.getPhysical()!=null) { 2182 mapping=m; 2183 //result = m.getResult(this,callerPath=pathInfo.substring(m.getVirtual().length()),format,matrix,null); 2184 rl=new RestRequestListener(m,pathInfo.substring(m.getVirtual().length()),matrix,format,hasFormatExtension,accept,contentType,null); 2185 break; 2186 } 2187 } 2188 2189 // default mapping 2190 if(mapping==null && defaultMapping!=null && defaultMapping.getPhysical()!=null) { 2191 mapping=defaultMapping; 2192 //result = mapping.getResult(this,callerPath=pathInfo,format,matrix,null); 2193 rl=new RestRequestListener(mapping,pathInfo,matrix,format,hasFormatExtension,accept,contentType,null); 2194 } 2195 2196 2197 //base = PageSourceImpl.best(config.getPageSources(this,null,relPath,true,false,true)); 2198 2199 2200 if(mapping==null || mapping.getPhysical()==null){ 2201 RestUtil.setStatus(this,404,"no rest service for ["+pathInfo+"] found"); 2202 } 2203 else { 2204 base=config.toPageSource(null, mapping.getPhysical(), null); 2205 listener=((MappingImpl)base.getMapping()).getApplicationListener(); 2206 listener.onRequest(this, base,rl); 2207 } 2208 2209 2210 2211 } 2212 catch(Throwable t) { 2213 PageException pe = Caster.toPageException(t); 2214 if(!Abort.isSilentAbort(pe)){ 2215 log(true); 2216 if(fdEnabled){ 2217 FDSignal.signal(pe, false); 2218 } 2219 if(listener==null) { 2220 if(base==null)listener=config.getApplicationListener(); 2221 else listener=((MappingImpl)base.getMapping()).getApplicationListener(); 2222 } 2223 listener.onError(this,pe); 2224 } 2225 else log(false); 2226 2227 if(throwExcpetion) throw pe; 2228 } 2229 finally { 2230 if(enablecfoutputonly>0){ 2231 setCFOutputOnly((short)0); 2232 } 2233 base=null; 2234 } 2235 } 2236 2237 @Override 2238 public void execute(String relPath, boolean throwExcpetion) throws PageException { 2239 execute(relPath, throwExcpetion, true); 2240 } 2241 public void execute(String relPath, boolean throwExcpetion, boolean onlyTopLevel) throws PageException { 2242 if((config.getScriptProtect()&ApplicationContext.SCRIPT_PROTECT_URL)>0) { 2243 relPath=ScriptProtect.translate(relPath); 2244 } 2245 2246 //SystemOut.printDate(config.getOutWriter(),"Call:"+relPath+" (id:"+getId()+";running-requests:"+config.getThreadQueue().size()+";)"); 2247 if(relPath.startsWith("/mapping-")){ 2248 base=null; 2249 int index = relPath.indexOf('/',9); 2250 if(index>-1){ 2251 String type = relPath.substring(9,index); 2252 if(type.equalsIgnoreCase("tag")){ 2253 base=getPageSource( 2254 new Mapping[]{config.getTagMapping(),config.getServerTagMapping()}, 2255 relPath.substring(index) 2256 ); 2257 } 2258 else if(type.equalsIgnoreCase("customtag")){ 2259 base=getPageSource( 2260 config.getCustomTagMappings(), 2261 relPath.substring(index) 2262 ); 2263 } 2264 /*else if(type.equalsIgnoreCase("gateway")){ 2265 base=config.getGatewayEngine().getMapping().getPageSource(relPath.substring(index)); 2266 if(!base.exists())base=getPageSource(relPath.substring(index)); 2267 }*/ 2268 } 2269 if(base==null) base=PageSourceImpl.best(config.getPageSources(this,null,relPath,onlyTopLevel,false,true)); 2270 } 2271 else base=PageSourceImpl.best(config.getPageSources(this,null,relPath,onlyTopLevel,false,true)); 2272 ApplicationListener listener=gatewayContext?config.getApplicationListener():((MappingImpl)base.getMapping()).getApplicationListener(); 2273 2274 2275 try { 2276 listener.onRequest(this,base,null); 2277 log(false); 2278 } 2279 catch(Throwable t) { 2280 PageException pe = Caster.toPageException(t); 2281 if(!Abort.isSilentAbort(pe)){ 2282 this.pe=pe; 2283 log(true); 2284 if(fdEnabled){ 2285 FDSignal.signal(pe, false); 2286 } 2287 listener.onError(this,pe); 2288 } 2289 else log(false); 2290 if(throwExcpetion) { 2291 ExceptionUtil.rethrowIfNecessary(t); 2292 throw pe; 2293 } 2294 } 2295 finally { 2296 if(enablecfoutputonly>0){ 2297 setCFOutputOnly((short)0); 2298 } 2299 if(!gatewayContext && getConfig().debug()) { 2300 try { 2301 listener.onDebug(this); 2302 } 2303 catch (PageException pe) { 2304 if(!Abort.isSilentAbort(pe))listener.onError(this,pe); 2305 } 2306 } 2307 base=null; 2308 } 2309 } 2310 2311 private void log(boolean error) { 2312 if(!isGatewayContext() && config.isMonitoringEnabled()) { 2313 RequestMonitor[] monitors = config.getRequestMonitors(); 2314 if(monitors!=null)for(int i=0;i<monitors.length;i++){ 2315 if(monitors[i].isLogEnabled()){ 2316 try { 2317 monitors[i].log(this,error); 2318 } 2319 catch (Throwable e) { 2320 ExceptionUtil.rethrowIfNecessary(e); 2321 } 2322 } 2323 } 2324 } 2325 } 2326 2327 private PageSource getPageSource(Mapping[] mappings, String relPath) { 2328 PageSource ps; 2329 //print.err(mappings.length); 2330 for(int i=0;i<mappings.length;i++) { 2331 ps = mappings[i].getPageSource(relPath); 2332 //print.err(ps.getDisplayPath()); 2333 if(ps.exists()) return ps; 2334 2335 } 2336 return null; 2337 } 2338 2339 2340 2341 @Override 2342 public void include(String relPath) throws ServletException,IOException { 2343 HTTPUtil.include(this, relPath); 2344 } 2345 2346 2347 @Override 2348 public void forward(String relPath) throws ServletException, IOException { 2349 HTTPUtil.forward(this, relPath); 2350 } 2351 2352 public void include(PageSource ps) throws ServletException { 2353 try { 2354 doInclude(ps); 2355 } catch (PageException pe) { 2356 throw new PageServletException(pe); 2357 } 2358 } 2359 2360 @Override 2361 public void clear() { 2362 try { 2363 //print.o(getOut().getClass().getName()); 2364 getOut().clear(); 2365 } catch (IOException e) {} 2366 } 2367 2368 @Override 2369 public long getRequestTimeout() { 2370 if(requestTimeout==-1) { 2371 if(applicationContext!=null) { 2372 return (applicationContext).getRequestTimeout().getMillis(); 2373 } 2374 requestTimeout=config.getRequestTimeout().getMillis(); 2375 } 2376 return requestTimeout; 2377 } 2378 2379 @Override 2380 public void setRequestTimeout(long requestTimeout) { 2381 this.requestTimeout = requestTimeout; 2382 } 2383 2384 @Override 2385 public String getCFID() { 2386 if(cfid==null) initIdAndToken(); 2387 return cfid; 2388 } 2389 2390 @Override 2391 public String getCFToken() { 2392 if(cftoken==null) initIdAndToken(); 2393 return cftoken; 2394 } 2395 2396 @Override 2397 public String getURLToken() { 2398 if(getConfig().getSessionType()==Config.SESSION_TYPE_J2EE) { 2399 HttpSession s = getSession(); 2400 return "CFID="+getCFID()+"&CFTOKEN="+getCFToken()+"&jsessionid="+(s!=null?getSession().getId():""); 2401 } 2402 return "CFID="+getCFID()+"&CFTOKEN="+getCFToken(); 2403 } 2404 2405 @Override 2406 public String getJSessionId() { 2407 if(getConfig().getSessionType()==Config.SESSION_TYPE_J2EE) { 2408 return getSession().getId(); 2409 } 2410 return null; 2411 } 2412 2413 2414 /** 2415 * initialize the cfid and the cftoken 2416 */ 2417 private void initIdAndToken() { 2418 boolean setCookie=true; 2419 // From URL 2420 Object oCfid = urlScope().get(KeyConstants._cfid,null); 2421 Object oCftoken = urlScope().get(KeyConstants._cftoken,null); 2422 2423 // Cookie 2424 if((oCfid==null || !Decision.isGUIdSimple(oCfid)) || oCftoken==null) { 2425 setCookie=false; 2426 oCfid = cookieScope().get(KeyConstants._cfid,null); 2427 oCftoken = cookieScope().get(KeyConstants._cftoken,null); 2428 } 2429 2430 // check cookie value 2431 if(oCfid!=null) { 2432 // cookie value is invalid, maybe from ACF 2433 if(!Decision.isGUIdSimple(oCfid)) { 2434 oCfid=null; 2435 oCftoken=null; 2436 Charset charset = getWebCharset(); 2437 2438 // check if we have multiple cookies with the name "cfid" and a other one is valid 2439 javax.servlet.http.Cookie[] cookies = getHttpServletRequest().getCookies(); 2440 String name,value; 2441 if(cookies!=null){ 2442 for(int i=0;i<cookies.length;i++){ 2443 name=ReqRspUtil.decode(cookies[i].getName(),charset.name(),false); 2444 2445 // CFID 2446 if("cfid".equalsIgnoreCase(name)) { 2447 value=ReqRspUtil.decode(cookies[i].getValue(),charset.name(),false); 2448 if(Decision.isGUIdSimple(value)) oCfid=value; 2449 ReqRspUtil.removeCookie(getHttpServletResponse(),name); 2450 } 2451 // CFToken 2452 else if("cftoken".equalsIgnoreCase(name)) { 2453 value=ReqRspUtil.decode(cookies[i].getValue(),charset.name(),false); 2454 if(isValidCfToken(value)) oCftoken=value; 2455 ReqRspUtil.removeCookie(getHttpServletResponse(),name); 2456 } 2457 } 2458 } 2459 2460 if(oCfid!=null) { 2461 setCookie=true; 2462 if(oCftoken==null)oCftoken="0"; 2463 } 2464 } 2465 } 2466 // New One 2467 if(oCfid==null || oCftoken==null) { 2468 setCookie=true; 2469 cfid=ScopeContext.getNewCFId(); 2470 cftoken=ScopeContext.getNewCFToken(); 2471 } 2472 else { 2473 cfid=Caster.toString(oCfid,null); 2474 cftoken=Caster.toString(oCftoken,null); 2475 } 2476 2477 if(setCookie && applicationContext.isSetClientCookies()) 2478 setClientCookies(); 2479 } 2480 2481 2482 private boolean isValidCfToken(String value) { 2483 return Operator.compare(value, "0")==0; 2484 } 2485 2486 2487 2488 public void resetIdAndToken() { 2489 cfid=ScopeContext.getNewCFId(); 2490 cftoken=ScopeContext.getNewCFToken(); 2491 2492 if(applicationContext.isSetClientCookies()) 2493 setClientCookies(); 2494 } 2495 2496 2497 private void setClientCookies() { 2498 2499 String domain = PageContextUtil.getCookieDomain( this ); 2500 cookieScope().setCookieEL( KeyConstants._cfid, cfid, CookieImpl.NEVER,false, "/", domain, true, true, false ); 2501 cookieScope().setCookieEL( KeyConstants._cftoken, cftoken, CookieImpl.NEVER,false, "/", domain, true, true, false ); 2502 } 2503 2504 2505 @Override 2506 public int getId() { 2507 return id; 2508 } 2509 2510 /** 2511 * @return returns the root JSP Writer 2512 * 2513 */ 2514 public CFMLWriter getRootOut() { 2515 return bodyContentStack.getBase(); 2516 } 2517 public JspWriter getRootWriter() { 2518 return bodyContentStack.getBase(); 2519 } 2520 2521 @Override 2522 public void setPsq(boolean psq) { 2523 this.psq=psq; 2524 } 2525 2526 @Override 2527 public boolean getPsq() { 2528 return psq; 2529 } 2530 2531 @Override 2532 public Locale getLocale() { 2533 Locale l = ((ApplicationContextPro)getApplicationContext()).getLocale(); 2534 if(l!=null) return l; 2535 if(locale!=null) return locale; 2536 return config.getLocale(); 2537 } 2538 2539 @Override 2540 public void setLocale(Locale locale) { 2541 2542 ((ApplicationContextPro)getApplicationContext()).setLocale(locale); 2543 this.locale=locale; 2544 HttpServletResponse rsp = getHttpServletResponse(); 2545 2546 Charset charEnc = ReqRspUtil.getCharacterEncoding(this,rsp); 2547 rsp.setLocale(locale); 2548 if(charEnc.equals(CharsetUtil.UTF8)) { 2549 rsp.setContentType("text/html; charset=UTF-8"); 2550 } 2551 else if(!charEnc.equals(ReqRspUtil.getCharacterEncoding(this,rsp))) { 2552 rsp.setContentType("text/html; charset=" + charEnc); 2553 } 2554 } 2555 2556 2557 @Override 2558 public void setLocale(String strLocale) throws ExpressionException { 2559 setLocale(Caster.toLocale(strLocale)); 2560 } 2561 2562 @Override 2563 public void setErrorPage(ErrorPage ep) { 2564 errorPagePool.setErrorPage(ep); 2565 } 2566 2567 @Override 2568 public Tag use(Class clazz) throws PageException { 2569 return use(clazz.getName()); 2570 } 2571 2572 @Override 2573 public Tag use(String tagClassName) throws PageException { 2574 return use(tagClassName,null,-1); 2575 } 2576 public Tag use(String tagClassName, String fullname,int attrType) throws PageException { 2577 2578 parentTag=currentTag; 2579 currentTag= tagHandlerPool.use(tagClassName); 2580 if(currentTag==parentTag) throw new ApplicationException(""); 2581 currentTag.setPageContext(this); 2582 currentTag.setParent(parentTag); 2583 if(attrType>=0 && fullname!=null) { 2584 Map<Collection.Key, Object> attrs = (applicationContext).getTagAttributeDefaultValues(fullname); 2585 if(attrs!=null) { 2586 TagUtil.setAttributes(this,currentTag, attrs, attrType); 2587 } 2588 } 2589 return currentTag; 2590 } 2591 2592 @Override 2593 public void reuse(Tag tag) throws PageException { 2594 currentTag=tag.getParent(); 2595 tagHandlerPool.reuse(tag); 2596 } 2597 2598 @Override 2599 public QueryCache getQueryCache() { 2600 throw new RuntimeException("funciton PageContext.getQueryCache() no longer supported"); 2601 } 2602 2603 @Override 2604 public void initBody(BodyTag bodyTag, int state) throws JspException { 2605 if (state != Tag.EVAL_BODY_INCLUDE) { 2606 bodyTag.setBodyContent(pushBody()); 2607 bodyTag.doInitBody(); 2608 } 2609 } 2610 2611 @Override 2612 public void releaseBody(BodyTag bodyTag, int state) { 2613 if(bodyTag instanceof TryCatchFinally) { 2614 ((TryCatchFinally)bodyTag).doFinally(); 2615 } 2616 if (state != Tag.EVAL_BODY_INCLUDE)popBody(); 2617 } 2618 2619 /* * 2620 * @return returns the cfml compiler 2621 * / 2622 public CFMLCompiler getCompiler() { 2623 return compiler; 2624 }*/ 2625 2626 @Override 2627 public void setVariablesScope(Variables variables) { 2628 this.variables=variables; 2629 undefinedScope().setVariableScope(variables); 2630 2631 if(variables instanceof ClosureScope) { 2632 variables = ((ClosureScope)variables).getVariables(); 2633 } 2634 2635 if(variables instanceof ComponentScope) { 2636 activeComponent=((ComponentScope)variables).getComponent(); 2637 } 2638 else { 2639 activeComponent=null; 2640 } 2641 } 2642 2643 @Override 2644 public Component getActiveComponent() { 2645 return activeComponent; 2646 } 2647 2648 @Override 2649 public Credential getRemoteUser() throws PageException { 2650 if(remoteUser==null) { 2651 Key name = KeyImpl.init(Login.getApplicationName(applicationContext)); 2652 Resource roles = config.getConfigDir().getRealResource("roles"); 2653 2654 if(applicationContext.getLoginStorage()==Scope.SCOPE_SESSION) { 2655 Object auth = sessionScope().get(name,null); 2656 if(auth!=null) { 2657 remoteUser=CredentialImpl.decode(auth,roles); 2658 } 2659 } 2660 else if(applicationContext.getLoginStorage()==Scope.SCOPE_COOKIE) { 2661 Object auth = cookieScope().get(name,null); 2662 if(auth!=null) { 2663 remoteUser=CredentialImpl.decode(auth,roles); 2664 } 2665 } 2666 } 2667 return remoteUser; 2668 } 2669 2670 @Override 2671 public void clearRemoteUser() { 2672 if(remoteUser!=null)remoteUser=null; 2673 String name=Login.getApplicationName(applicationContext); 2674 2675 cookieScope().removeEL(KeyImpl.init(name)); 2676 try { 2677 sessionScope().removeEL(KeyImpl.init(name)); 2678 } catch (PageException e) {} 2679 2680 } 2681 2682 @Override 2683 public void setRemoteUser(Credential remoteUser) { 2684 this.remoteUser = remoteUser; 2685 } 2686 2687 @Override 2688 public VariableUtil getVariableUtil() { 2689 return variableUtil; 2690 } 2691 2692 @Override 2693 public void throwCatch() throws PageException { 2694 if(exception!=null) throw exception; 2695 throw new ApplicationException("invalid context for tag/script expression rethow"); 2696 } 2697 2698 @Override 2699 public PageException setCatch(Throwable t) { 2700 ExceptionUtil.rethrowIfNecessary(t); 2701 if(t==null) { 2702 exception=null; 2703 undefinedScope().removeEL(KeyConstants._cfcatch); 2704 } 2705 else { 2706 exception = Caster.toPageException(t); 2707 undefinedScope().setEL(KeyConstants._cfcatch,exception.getCatchBlock(config)); 2708 if(!gatewayContext && config.debug() && config.hasDebugOptions(ConfigImpl.DEBUG_EXCEPTION)) debugger.addException(config,exception); 2709 } 2710 return exception; 2711 } 2712 2713 public void setCatch(PageException pe) { 2714 exception = pe; 2715 if(pe==null) { 2716 undefinedScope().removeEL(KeyConstants._cfcatch); 2717 } 2718 else { 2719 undefinedScope().setEL(KeyConstants._cfcatch,pe.getCatchBlock(config)); 2720 if(!gatewayContext && config.debug() && config.hasDebugOptions(ConfigImpl.DEBUG_EXCEPTION)) debugger.addException(config,exception); 2721 } 2722 } 2723 2724 public void setCatch(PageException pe,boolean caught, boolean store) { 2725 if(fdEnabled){ 2726 FDSignal.signal(pe, caught); 2727 } 2728 exception = pe; 2729 if(store){ 2730 if(pe==null) { 2731 undefinedScope().removeEL(KeyConstants._cfcatch); 2732 } 2733 else { 2734 undefinedScope().setEL(KeyConstants._cfcatch,pe.getCatchBlock(config)); 2735 if(!gatewayContext && config.debug() && config.hasDebugOptions(ConfigImpl.DEBUG_EXCEPTION)) debugger.addException(config,exception); 2736 } 2737 } 2738 } 2739 2740 /** 2741 * @return return current catch 2742 */ 2743 public PageException getCatch() { 2744 return exception; 2745 } 2746 2747 @Override 2748 public void clearCatch() { 2749 exception = null; 2750 undefinedScope().removeEL(KeyConstants._cfcatch); 2751 } 2752 2753 @Override 2754 public void addPageSource(PageSource ps, boolean alsoInclude) { 2755 pathList.add(ps); 2756 if(alsoInclude) 2757 includePathList.add(ps); 2758 } 2759 2760 2761 public void addPageSource(PageSource ps, PageSource psInc) { 2762 pathList.add(ps); 2763 if(psInc!=null) 2764 includePathList.add(psInc); 2765 } 2766 2767 @Override 2768 public void removeLastPageSource(boolean alsoInclude) { 2769 if(!pathList.isEmpty())pathList.removeLast(); 2770 if(alsoInclude && !includePathList.isEmpty()) 2771 includePathList.removeLast(); 2772 } 2773 2774 2775 public UDF[] getUDFs() { 2776 return udfs.toArray(new UDF[udfs.size()]); 2777 } 2778 2779 public void addUDF(UDF udf) { 2780 udfs.add(udf); 2781 } 2782 2783 public void removeUDF() { 2784 if(!udfs.isEmpty())udfs.removeLast(); 2785 } 2786 2787 @Override 2788 public FTPPool getFTPPool() { 2789 return null; 2790 } 2791 public FTPPoolImpl getFTPPoolImpl() { 2792 return ftpPool; 2793 } 2794 2795 /* * 2796 * @return Returns the manager. 2797 * / 2798 public DataSourceManager getManager() { 2799 return manager; 2800 }*/ 2801 2802 @Override 2803 public ApplicationContext getApplicationContext() { 2804 return applicationContext; 2805 } 2806 2807 @Override 2808 public void setApplicationContext(ApplicationContext applicationContext) { 2809 2810 session=null; 2811 application=null; 2812 client=null; 2813 this.applicationContext = (ApplicationContextPro) applicationContext; 2814 2815 int scriptProtect = applicationContext.getScriptProtect(); 2816 2817 // ScriptProtecting 2818 if(config.mergeFormAndURL()) { 2819 form.setScriptProtecting(applicationContext, 2820 (scriptProtect&ApplicationContext.SCRIPT_PROTECT_FORM)>0 2821 || 2822 (scriptProtect&ApplicationContext.SCRIPT_PROTECT_URL)>0); 2823 } 2824 else { 2825 form.setScriptProtecting(applicationContext,(scriptProtect&ApplicationContext.SCRIPT_PROTECT_FORM)>0); 2826 url.setScriptProtecting(applicationContext,(scriptProtect&ApplicationContext.SCRIPT_PROTECT_URL)>0); 2827 } 2828 cookie.setScriptProtecting(applicationContext,(scriptProtect&ApplicationContext.SCRIPT_PROTECT_COOKIE)>0); 2829 2830 // CGI 2831 cgiR.setScriptProtecting(applicationContext,(scriptProtect&ApplicationContext.SCRIPT_PROTECT_CGI)>0); 2832 cgiRW.setScriptProtecting(applicationContext,(scriptProtect&ApplicationContext.SCRIPT_PROTECT_CGI)>0); 2833 undefined.reinitialize(this); 2834 } 2835 2836 /** 2837 * @return return value of method "onApplicationStart" or true 2838 * @throws PageException 2839 */ 2840 public boolean initApplicationContext(ApplicationListener listener) throws PageException { 2841 boolean initSession=false; 2842 //AppListenerSupport listener = (AppListenerSupport) config.get ApplicationListener(); 2843 KeyLock<String> lock = config.getContextLock(); 2844 String name=StringUtil.emptyIfNull(applicationContext.getName()); 2845 String token=name+":"+getCFID(); 2846 2847 Lock tokenLock = lock.lock(token,getRequestTimeout()); 2848 //print.o("outer-lock :"+token); 2849 try { 2850 // check session before executing any code 2851 initSession=applicationContext.isSetSessionManagement() && listener.hasOnSessionStart(this) && !scopeContext.hasExistingSessionScope(this); 2852 2853 // init application 2854 2855 Lock nameLock = lock.lock(name,getRequestTimeout()); 2856 //print.o("inner-lock :"+token); 2857 try { 2858 RefBoolean isNew=new RefBooleanImpl(false); 2859 application=scopeContext.getApplicationScope(this,isNew);// this is needed that the application scope is initilized 2860 if(isNew.toBooleanValue()) { 2861 try { 2862 if(!listener.onApplicationStart(this)) { 2863 scopeContext.removeApplicationScope(this); 2864 return false; 2865 } 2866 } catch (PageException pe) { 2867 scopeContext.removeApplicationScope(this); 2868 throw pe; 2869 } 2870 } 2871 } 2872 finally{ 2873 //print.o("inner-unlock:"+token); 2874 lock.unlock(nameLock); 2875 } 2876 2877 // init session 2878 if(initSession) { 2879 scopeContext.getSessionScope(this, DUMMY_BOOL);// this is needed that the session scope is initilized 2880 listener.onSessionStart(this); 2881 } 2882 } 2883 finally{ 2884 //print.o("outer-unlock:"+token); 2885 lock.unlock(tokenLock); 2886 } 2887 return true; 2888 } 2889 2890 2891 /** 2892 * @return the scope factory 2893 */ 2894 public ScopeFactory getScopeFactory() { 2895 return scopeFactory; 2896 } 2897 2898 2899 2900 2901 @Override 2902 public Tag getCurrentTag() { 2903 return currentTag; 2904 } 2905 2906 @Override 2907 public long getStartTime() { 2908 return startTime; 2909 } 2910 2911 @Override 2912 public Thread getThread() { 2913 return thread; 2914 } 2915 2916 2917 2918 public void setThread(Thread thread) { 2919 this.thread=thread; 2920 } 2921 2922 // FUTURE add as long 2923 @Override 2924 public int getExecutionTime() { 2925 return (int)executionTime; 2926 } 2927 2928 public long getExecutionTimeLong() { 2929 return executionTime; 2930 } 2931 2932 @Override 2933 public void setExecutionTime(int executionTime) { 2934 this.executionTime = executionTime; 2935 } 2936 2937 public void setExecutionTimeLong(long executionTime) { 2938 this.executionTime = executionTime; 2939 } 2940 2941 @Override 2942 public synchronized void compile(PageSource pageSource) throws PageException { 2943 Resource classRootDir = pageSource.getMapping().getClassRootDirectory(); 2944 2945 try { 2946 config.getCompiler().compile( 2947 config, 2948 pageSource, 2949 config.getTLDs(), 2950 config.getFLDs(), 2951 classRootDir, 2952 pageSource.getJavaName() 2953 ); 2954 } catch (Exception e) { 2955 throw Caster.toPageException(e); 2956 } 2957 } 2958 2959 @Override 2960 public void compile(String relPath) throws PageException { 2961 SystemOut.printDate("method PageContext.compile(String) should no longer be used!"); 2962 compile(PageSourceImpl.best(getRelativePageSources(relPath))); 2963 } 2964 2965 public HttpServlet getServlet() { 2966 return servlet; 2967 } 2968 2969 @Override 2970 public lucee.runtime.Component loadComponent(String compPath) throws PageException { 2971 return ComponentLoader.loadComponent(this,null,compPath,null,null); 2972 } 2973 2974 /** 2975 * @return the base 2976 */ 2977 public PageSource getBase() { 2978 return base; 2979 } 2980 2981 /** 2982 * @param base the base to set 2983 */ 2984 public void setBase(PageSource base) { 2985 this.base = base; 2986 } 2987 2988 /** 2989 * @return the isCFCRequest 2990 */ 2991 public boolean isCFCRequest() { 2992 return isCFCRequest; 2993 } 2994 2995 @Override 2996 public DataSourceManager getDataSourceManager() { 2997 return manager; 2998 } 2999 3000 @Override 3001 public Object evaluate(String expression) throws PageException { 3002 return new CFMLExpressionInterpreter(false).interpret(this,expression); 3003 } 3004 3005 @Override 3006 public String serialize(Object expression) throws PageException { 3007 return Serialize.call(this, expression); 3008 } 3009 3010 /** 3011 * @return the activeUDF 3012 */ 3013 public UDF getActiveUDF() { 3014 return activeUDF; 3015 } 3016 public Collection.Key getActiveUDFCalledName() { 3017 return activeUDFCalledName; 3018 } 3019 public void setActiveUDFCalledName(Collection.Key activeUDFCalledName) { 3020 this.activeUDFCalledName=activeUDFCalledName; 3021 } 3022 3023 /** 3024 * @param activeUDF the activeUDF to set 3025 */ 3026 public void setActiveUDF(UDF activeUDF) { 3027 this.activeUDF = activeUDF; 3028 } 3029 3030 @Override 3031 public CFMLFactory getCFMLFactory() { 3032 return config.getFactory(); 3033 } 3034 3035 @Override 3036 public PageContext getParentPageContext() { 3037 return parent; 3038 } 3039 3040 3041 @Override 3042 public String[] getThreadScopeNames() { 3043 if(threads==null)return new String[0]; 3044 return CollectionUtil.keysAsString(threads); 3045 //Set ks = threads.keySet(); 3046 //return (String[]) ks.toArray(new String[ks.size()]); 3047 } 3048 3049 @Override 3050 public Threads getThreadScope(String name) { 3051 return getThreadScope(KeyImpl.init(name)); 3052 } 3053 3054 public Threads getThreadScope(Collection.Key name) { 3055 if(threads==null)threads=new StructImpl(); 3056 Object obj = threads.get(name,null); 3057 if(obj instanceof Threads)return (Threads) obj; 3058 return null; 3059 } 3060 3061 public Object getThreadScope(Collection.Key name,Object defaultValue) { 3062 if(threads==null)threads=new StructImpl(); 3063 if(name.equalsIgnoreCase(KeyConstants._cfthread)) return threads; 3064 return threads.get(name,defaultValue); 3065 } 3066 3067 public Object getThreadScope(String name,Object defaultValue) { 3068 if(threads==null)threads=new StructImpl(); 3069 if(name.equalsIgnoreCase(KeyConstants._cfthread.getLowerString())) return threads; 3070 return threads.get(KeyImpl.init(name),defaultValue); 3071 } 3072 3073 @Override 3074 public void setThreadScope(String name,Threads ct) { 3075 hasFamily=true; 3076 if(threads==null) threads=new StructImpl(); 3077 threads.setEL(KeyImpl.init(name), ct); 3078 } 3079 3080 public void setThreadScope(Collection.Key name,Threads ct) { 3081 hasFamily=true; 3082 if(threads==null) threads=new StructImpl(); 3083 threads.setEL(name, ct); 3084 } 3085 3086 @Override 3087 public boolean hasFamily() { 3088 return hasFamily; 3089 } 3090 3091 3092 public DatasourceConnection _getConnection(String datasource, String user,String pass) throws PageException { 3093 return _getConnection(config.getDataSource(datasource),user,pass); 3094 } 3095 3096 public DatasourceConnection _getConnection(DataSource ds, String user,String pass) throws PageException { 3097 3098 String id=DatasourceConnectionPool.createId(ds,user,pass); 3099 DatasourceConnection dc=transConns.get(id); 3100 if(dc!=null && DatasourceConnectionPool.isValid(dc,null)){ 3101 return dc; 3102 } 3103 dc=config.getDatasourceConnectionPool().getDatasourceConnection(ds, user, pass); 3104 transConns.put(id, dc); 3105 return dc; 3106 } 3107 3108 @Override 3109 public TimeZone getTimeZone() { 3110 TimeZone tz = ((ApplicationContextPro)getApplicationContext()).getTimeZone(); 3111 if(tz!=null) return tz; 3112 if(timeZone!=null) return timeZone; 3113 return config.getTimeZone(); 3114 } 3115 3116 @Override 3117 public void setTimeZone(TimeZone timeZone) { 3118 ((ApplicationContextPro)getApplicationContext()).setTimeZone(timeZone); 3119 this.timeZone=timeZone; 3120 } 3121 3122 3123 /** 3124 * @return the requestId 3125 */ 3126 public int getRequestId() { 3127 return requestId; 3128 } 3129 3130 private Set<String> pagesUsed=new HashSet<String>(); 3131 3132 private Stack<ActiveQuery> activeQueries=new Stack<ActiveQuery>(); 3133 private Stack<ActiveLock> activeLocks=new Stack<ActiveLock>(); 3134 3135 public boolean isTrusted(Page page) { 3136 if(page==null)return false; 3137 3138 short it = ((MappingImpl)page.getPageSource().getMapping()).getInspectTemplate(); 3139 if(it==ConfigImpl.INSPECT_NEVER)return true; 3140 if(it==ConfigImpl.INSPECT_ALWAYS)return false; 3141 3142 return pagesUsed.contains(""+page.hashCode()); 3143 } 3144 3145 public void setPageUsed(Page page) { 3146 pagesUsed.add(""+page.hashCode()); 3147 } 3148 3149 @Override 3150 public void exeLogStart(int position,String id){ 3151 if(execLog!=null)execLog.start(position, id); 3152 } 3153 3154 @Override 3155 public void exeLogEnd(int position,String id){ 3156 if(execLog!=null)execLog.end(position, id); 3157 } 3158 3159 3160 /** 3161 * @param create if set to true, lucee creates a session when not exist 3162 * @return 3163 * @throws PageException 3164 */ 3165 public ORMSession getORMSession(boolean create) throws PageException { 3166 3167 if(ormSession==null || !ormSession.isValid()) { 3168 if(!create) return null; 3169 ormSession=config.getORMEngine(this).createSession(this); 3170 } 3171 DatasourceManagerImpl manager = (DatasourceManagerImpl) getDataSourceManager(); 3172 manager.add(this,ormSession); 3173 3174 return ormSession; 3175 } 3176 3177 public ClassLoader getClassLoader() throws IOException { 3178 return getResourceClassLoader(); 3179 } 3180 3181 public ClassLoader getClassLoader(Resource[] reses) throws IOException{ 3182 return getResourceClassLoader().getCustomResourceClassLoader(reses); 3183 } 3184 3185 private ResourceClassLoader getResourceClassLoader() throws IOException { 3186 JavaSettingsImpl js = (JavaSettingsImpl) applicationContext.getJavaSettings(); 3187 if(js!=null) { 3188 return config.getResourceClassLoader().getCustomResourceClassLoader(js.getResourcesTranslated()); 3189 } 3190 return config.getResourceClassLoader(); 3191 } 3192 3193 public ClassLoader getRPCClassLoader(boolean reload) throws IOException { 3194 JavaSettingsImpl js = (JavaSettingsImpl) applicationContext.getJavaSettings(); 3195 if(js!=null) { 3196 return ((PhysicalClassLoader)config.getRPCClassLoader(reload)).getCustomClassLoader(js.getResourcesTranslated(),reload); 3197 } 3198 return config.getRPCClassLoader(reload); 3199 } 3200 3201 3202 3203 public void resetSession() { 3204 this.session=null; 3205 } 3206 /** 3207 * @return the gatewayContext 3208 */ 3209 public boolean isGatewayContext() { 3210 return gatewayContext; 3211 } 3212 3213 3214 3215 /** 3216 * @param gatewayContext the gatewayContext to set 3217 */ 3218 public void setGatewayContext(boolean gatewayContext) { 3219 this.gatewayContext = gatewayContext; 3220 } 3221 3222 3223 3224 public void setServerPassword(String serverPassword) { 3225 this.serverPassword=serverPassword; 3226 } 3227 public String getServerPassword() { 3228 return serverPassword; 3229 } 3230 3231 public short getSessionType() { 3232 if(isGatewayContext())return Config.SESSION_TYPE_CFML; 3233 return applicationContext.getSessionType(); 3234 } 3235 3236 // this is just a wrapper method for ACF 3237 public Scope SymTab_findBuiltinScope(String name) throws PageException { 3238 return scope(name, null); 3239 } 3240 3241// FUTURE add to PageContext 3242 public DataSource getDataSource(String datasource) throws PageException { 3243 DataSource ds = ((ApplicationContextPro)getApplicationContext()).getDataSource(datasource,null); 3244 if(ds!=null) return ds; 3245 ds=getConfig().getDataSource(datasource,null); 3246 if(ds!=null) return ds; 3247 3248 throw DatabaseException.notFoundException(this, datasource); 3249 } 3250 3251// FUTURE add to PageContext 3252 public DataSource getDataSource(String datasource, DataSource defaultValue) { 3253 DataSource ds = ((ApplicationContextPro)getApplicationContext()).getDataSource(datasource,null); 3254 if(ds==null) ds=getConfig().getDataSource(datasource,defaultValue); 3255 return ds; 3256 } 3257 3258 public void setActiveQuery(ActiveQuery activeQuery) { 3259 this.activeQueries.add(activeQuery); 3260 } 3261 3262 public ActiveQuery[] getActiveQueries() { 3263 return activeQueries.toArray(new ActiveQuery[activeQueries.size()]); 3264 } 3265 3266 public ActiveQuery releaseActiveQuery() { 3267 return activeQueries.pop(); 3268 } 3269 3270 public void setActiveLock(ActiveLock activeLock) { 3271 this.activeLocks.add(activeLock); 3272 } 3273 3274 public ActiveLock[] getActiveLocks() { 3275 return activeLocks.toArray(new ActiveLock[activeLocks.size()]); 3276 } 3277 3278 public ActiveLock releaseActiveLock() { 3279 return activeLocks.pop(); 3280 } 3281 3282 public PageException getPageException() { 3283 return pe; 3284 } 3285 3286 // FUTURE add this methods to the loader 3287 public Charset getResourceCharset() { 3288 Charset cs = ((ApplicationContextPro)getApplicationContext()).getResourceCharset(); 3289 if(cs!=null) return cs; 3290 return config._getResourceCharset(); 3291 } 3292 3293 public Charset getWebCharset() { 3294 Charset cs = ((ApplicationContextPro)getApplicationContext()).getWebCharset(); 3295 if(cs!=null) return cs; 3296 return config._getWebCharset(); 3297 } 3298 3299 public short getScopeCascadingType() { 3300 ApplicationContextPro ac = ((ApplicationContextPro)getApplicationContext()); 3301 if(ac==null) return config.getScopeCascadingType(); 3302 return ac.getScopeCascading(); 3303 } 3304 3305 public boolean getTypeChecking() { 3306 ApplicationContextPro ac = ((ApplicationContextPro)getApplicationContext()); 3307 if(ac==null) return config.getTypeChecking(); 3308 return ac.getTypeChecking(); 3309 } 3310 3311 3312 3313 public boolean getAllowCompression() { 3314 ApplicationContextPro ac = ((ApplicationContextPro)getApplicationContext()); 3315 if(ac==null) return config.allowCompression(); 3316 return ac.getAllowCompression(); 3317 } 3318 3319 public boolean getSuppressContent() { 3320 ApplicationContextPro ac = ((ApplicationContextPro)getApplicationContext()); 3321 if(ac==null) return config.isSuppressContent(); 3322 return ac.getSuppressContent(); 3323 } 3324 3325 3326 public void registerLazyStatement(Statement s) { 3327 if(lazyStats==null)lazyStats=new ArrayList<Statement>(); 3328 lazyStats.add(s); 3329 } 3330 3331 3332 3333 public void setAppListenerType(int appListenerType) { 3334 this.appListenerType=appListenerType; 3335 } 3336 public int getAppListenerType() { 3337 return appListenerType; 3338 } 3339 3340 3341 3342 public void setTimestampWithTSOffset(boolean literalTimestampWithTSOffset) { 3343 this.literalTimestampWithTSOffset=literalTimestampWithTSOffset; 3344 } 3345 3346 public boolean getTimestampWithTSOffset() { 3347 return literalTimestampWithTSOffset; 3348 } 3349 3350 3351}