001: /*
002: * Copyright 1999,2004 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.jasper.runtime;
018:
019: import java.io.IOException;
020: import java.io.Writer;
021: import java.security.AccessController;
022: import java.security.PrivilegedAction;
023: import java.security.PrivilegedActionException;
024: import java.security.PrivilegedExceptionAction;
025: import java.util.Enumeration;
026: import java.util.Hashtable;
027:
028: import javax.servlet.Servlet;
029: import javax.servlet.ServletConfig;
030: import javax.servlet.ServletContext;
031: import javax.servlet.ServletException;
032: import javax.servlet.ServletRequest;
033: import javax.servlet.ServletResponse;
034: import javax.servlet.http.HttpServletRequest;
035: import javax.servlet.http.HttpServletResponse;
036: import javax.servlet.http.HttpSession;
037: import javax.servlet.jsp.JspException;
038: import javax.servlet.jsp.JspFactory;
039: import javax.servlet.jsp.JspWriter;
040: import javax.servlet.jsp.PageContext;
041: import javax.servlet.jsp.el.ELException;
042: import javax.servlet.jsp.el.ExpressionEvaluator;
043: import javax.servlet.jsp.el.VariableResolver;
044: import javax.servlet.jsp.tagext.BodyContent;
045:
046: import org.apache.commons.el.ExpressionEvaluatorImpl;
047: import org.apache.commons.el.VariableResolverImpl;
048: import org.apache.commons.logging.Log;
049: import org.apache.commons.logging.LogFactory;
050: import org.apache.jasper.Constants;
051: import org.apache.jasper.compiler.Localizer;
052:
053: /**
054: * Implementation of the PageContext class from the JSP spec.
055: * Also doubles as a VariableResolver for the EL.
056: *
057: * @author Anil K. Vijendran
058: * @author Larry Cable
059: * @author Hans Bergsten
060: * @author Pierre Delisle
061: * @author Mark Roth
062: * @author Jan Luehe
063: */
064: public class PageContextImpl extends PageContext implements
065: VariableResolver {
066:
067: // Logger
068: private static Log log = LogFactory.getLog(PageContextImpl.class);
069:
070: // The expression evaluator, for evaluating EL expressions.
071: private static ExpressionEvaluatorImpl elExprEval = new ExpressionEvaluatorImpl(
072: false);
073:
074: // The variable resolver, for evaluating EL expressions.
075: private VariableResolverImpl variableResolver;
076:
077: private BodyContentImpl[] outs;
078: private int depth;
079:
080: // per-servlet state
081: private Servlet servlet;
082: private ServletConfig config;
083: private ServletContext context;
084: private JspFactory factory;
085: private boolean needsSession;
086: private String errorPageURL;
087: private boolean autoFlush;
088: private int bufferSize;
089:
090: // page-scope attributes
091: private transient Hashtable attributes;
092:
093: // per-request state
094: private transient ServletRequest request;
095: private transient ServletResponse response;
096: private transient Object page;
097: private transient HttpSession session;
098: private boolean isIncluded;
099:
100: // initial output stream
101: private transient JspWriter out;
102: private transient JspWriterImpl baseOut;
103:
104: /*
105: * Constructor.
106: */
107: PageContextImpl(JspFactory factory) {
108: this .factory = factory;
109: this .variableResolver = new VariableResolverImpl(this );
110: this .outs = new BodyContentImpl[0];
111: this .attributes = new Hashtable(16);
112: this .depth = -1;
113: }
114:
115: public void initialize(Servlet servlet, ServletRequest request,
116: ServletResponse response, String errorPageURL,
117: boolean needsSession, int bufferSize, boolean autoFlush)
118: throws IOException {
119:
120: _initialize(servlet, request, response, errorPageURL,
121: needsSession, bufferSize, autoFlush);
122: }
123:
124: private void _initialize(Servlet servlet, ServletRequest request,
125: ServletResponse response, String errorPageURL,
126: boolean needsSession, int bufferSize, boolean autoFlush)
127: throws IOException {
128:
129: // initialize state
130: this .servlet = servlet;
131: this .config = servlet.getServletConfig();
132: this .context = config.getServletContext();
133: this .needsSession = needsSession;
134: this .errorPageURL = errorPageURL;
135: this .bufferSize = bufferSize;
136: this .autoFlush = autoFlush;
137: this .request = request;
138: this .response = response;
139:
140: // Setup session (if required)
141: if (request instanceof HttpServletRequest && needsSession)
142: this .session = ((HttpServletRequest) request).getSession();
143: if (needsSession && session == null)
144: throw new IllegalStateException(
145: "Page needs a session and none is available");
146:
147: // initialize the initial out ...
148: depth = -1;
149: if (this .baseOut == null) {
150: this .baseOut = new JspWriterImpl(response, bufferSize,
151: autoFlush);
152: } else {
153: this .baseOut.init(response, bufferSize, autoFlush);
154: }
155: this .out = baseOut;
156:
157: // register names/values as per spec
158: setAttribute(OUT, this .out);
159: setAttribute(REQUEST, request);
160: setAttribute(RESPONSE, response);
161:
162: if (session != null)
163: setAttribute(SESSION, session);
164:
165: setAttribute(PAGE, servlet);
166: setAttribute(CONFIG, config);
167: setAttribute(PAGECONTEXT, this );
168: setAttribute(APPLICATION, context);
169:
170: isIncluded = request
171: .getAttribute("javax.servlet.include.servlet_path") != null;
172: }
173:
174: public void release() {
175: out = baseOut;
176: try {
177: if (isIncluded) {
178: ((JspWriterImpl) out).flushBuffer();
179: // push it into the including jspWriter
180: } else {
181: // Old code:
182: //out.flush();
183: // Do not flush the buffer even if we're not included (i.e.
184: // we are the main page. The servlet will flush it and close
185: // the stream.
186: ((JspWriterImpl) out).flushBuffer();
187: }
188: } catch (IOException ex) {
189: log.warn("Internal error flushing the buffer in release()");
190: }
191:
192: servlet = null;
193: config = null;
194: context = null;
195: needsSession = false;
196: errorPageURL = null;
197: bufferSize = JspWriter.DEFAULT_BUFFER;
198: autoFlush = true;
199: request = null;
200: response = null;
201: depth = -1;
202: baseOut.recycle();
203: session = null;
204:
205: attributes.clear();
206: }
207:
208: public Object getAttribute(final String name) {
209:
210: if (name == null) {
211: throw new NullPointerException(Localizer
212: .getMessage("jsp.error.attribute.null_name"));
213: }
214:
215: if (System.getSecurityManager() != null) {
216: return AccessController
217: .doPrivileged(new PrivilegedAction() {
218: public Object run() {
219: return doGetAttribute(name);
220: }
221: });
222: } else {
223: return doGetAttribute(name);
224: }
225:
226: }
227:
228: private Object doGetAttribute(String name) {
229: return attributes.get(name);
230: }
231:
232: public Object getAttribute(final String name, final int scope) {
233:
234: if (name == null) {
235: throw new NullPointerException(Localizer
236: .getMessage("jsp.error.attribute.null_name"));
237: }
238:
239: if (System.getSecurityManager() != null) {
240: return AccessController
241: .doPrivileged(new PrivilegedAction() {
242: public Object run() {
243: return doGetAttribute(name, scope);
244: }
245: });
246: } else {
247: return doGetAttribute(name, scope);
248: }
249:
250: }
251:
252: private Object doGetAttribute(String name, int scope) {
253: switch (scope) {
254: case PAGE_SCOPE:
255: return attributes.get(name);
256:
257: case REQUEST_SCOPE:
258: return request.getAttribute(name);
259:
260: case SESSION_SCOPE:
261: if (session == null) {
262: throw new IllegalStateException(Localizer
263: .getMessage("jsp.error.page.noSession"));
264: }
265: return session.getAttribute(name);
266:
267: case APPLICATION_SCOPE:
268: return context.getAttribute(name);
269:
270: default:
271: throw new IllegalArgumentException("Invalid scope");
272: }
273: }
274:
275: public void setAttribute(final String name, final Object attribute) {
276:
277: if (name == null) {
278: throw new NullPointerException(Localizer
279: .getMessage("jsp.error.attribute.null_name"));
280: }
281:
282: if (System.getSecurityManager() != null) {
283: AccessController.doPrivileged(new PrivilegedAction() {
284: public Object run() {
285: doSetAttribute(name, attribute);
286: return null;
287: }
288: });
289: } else {
290: doSetAttribute(name, attribute);
291: }
292: }
293:
294: private void doSetAttribute(String name, Object attribute) {
295: if (attribute != null) {
296: attributes.put(name, attribute);
297: } else {
298: removeAttribute(name, PAGE_SCOPE);
299: }
300: }
301:
302: public void setAttribute(final String name, final Object o,
303: final int scope) {
304:
305: if (name == null) {
306: throw new NullPointerException(Localizer
307: .getMessage("jsp.error.attribute.null_name"));
308: }
309:
310: if (System.getSecurityManager() != null) {
311: AccessController.doPrivileged(new PrivilegedAction() {
312: public Object run() {
313: doSetAttribute(name, o, scope);
314: return null;
315: }
316: });
317: } else {
318: doSetAttribute(name, o, scope);
319: }
320:
321: }
322:
323: private void doSetAttribute(String name, Object o, int scope) {
324: if (o != null) {
325: switch (scope) {
326: case PAGE_SCOPE:
327: attributes.put(name, o);
328: break;
329:
330: case REQUEST_SCOPE:
331: request.setAttribute(name, o);
332: break;
333:
334: case SESSION_SCOPE:
335: if (session == null) {
336: throw new IllegalStateException(Localizer
337: .getMessage("jsp.error.page.noSession"));
338: }
339: session.setAttribute(name, o);
340: break;
341:
342: case APPLICATION_SCOPE:
343: context.setAttribute(name, o);
344: break;
345:
346: default:
347: throw new IllegalArgumentException("Invalid scope");
348: }
349: } else {
350: removeAttribute(name, scope);
351: }
352: }
353:
354: public void removeAttribute(final String name, final int scope) {
355:
356: if (name == null) {
357: throw new NullPointerException(Localizer
358: .getMessage("jsp.error.attribute.null_name"));
359: }
360: if (System.getSecurityManager() != null) {
361: AccessController.doPrivileged(new PrivilegedAction() {
362: public Object run() {
363: doRemoveAttribute(name, scope);
364: return null;
365: }
366: });
367: } else {
368: doRemoveAttribute(name, scope);
369: }
370: }
371:
372: private void doRemoveAttribute(String name, int scope) {
373: switch (scope) {
374: case PAGE_SCOPE:
375: attributes.remove(name);
376: break;
377:
378: case REQUEST_SCOPE:
379: request.removeAttribute(name);
380: break;
381:
382: case SESSION_SCOPE:
383: if (session == null) {
384: throw new IllegalStateException(Localizer
385: .getMessage("jsp.error.page.noSession"));
386: }
387: session.removeAttribute(name);
388: break;
389:
390: case APPLICATION_SCOPE:
391: context.removeAttribute(name);
392: break;
393:
394: default:
395: throw new IllegalArgumentException("Invalid scope");
396: }
397: }
398:
399: public int getAttributesScope(final String name) {
400:
401: if (name == null) {
402: throw new NullPointerException(Localizer
403: .getMessage("jsp.error.attribute.null_name"));
404: }
405:
406: if (System.getSecurityManager() != null) {
407: return ((Integer) AccessController
408: .doPrivileged(new PrivilegedAction() {
409: public Object run() {
410: return new Integer(
411: doGetAttributeScope(name));
412: }
413: })).intValue();
414: } else {
415: return doGetAttributeScope(name);
416: }
417: }
418:
419: private int doGetAttributeScope(String name) {
420: if (attributes.get(name) != null)
421: return PAGE_SCOPE;
422:
423: if (request.getAttribute(name) != null)
424: return REQUEST_SCOPE;
425:
426: if (session != null) {
427: if (session.getAttribute(name) != null)
428: return SESSION_SCOPE;
429: }
430:
431: if (context.getAttribute(name) != null)
432: return APPLICATION_SCOPE;
433:
434: return 0;
435: }
436:
437: public Object findAttribute(final String name) {
438: if (System.getSecurityManager() != null) {
439: return AccessController
440: .doPrivileged(new PrivilegedAction() {
441: public Object run() {
442: if (name == null) {
443: throw new NullPointerException(
444: Localizer
445: .getMessage("jsp.error.attribute.null_name"));
446: }
447:
448: return doFindAttribute(name);
449: }
450: });
451: } else {
452: if (name == null) {
453: throw new NullPointerException(Localizer
454: .getMessage("jsp.error.attribute.null_name"));
455: }
456:
457: return doFindAttribute(name);
458: }
459: }
460:
461: private Object doFindAttribute(String name) {
462:
463: Object o = attributes.get(name);
464: if (o != null)
465: return o;
466:
467: o = request.getAttribute(name);
468: if (o != null)
469: return o;
470:
471: if (session != null) {
472: o = session.getAttribute(name);
473: if (o != null)
474: return o;
475: }
476:
477: return context.getAttribute(name);
478: }
479:
480: public Enumeration getAttributeNamesInScope(final int scope) {
481: if (System.getSecurityManager() != null) {
482: return (Enumeration) AccessController
483: .doPrivileged(new PrivilegedAction() {
484: public Object run() {
485: return doGetAttributeNamesInScope(scope);
486: }
487: });
488: } else {
489: return doGetAttributeNamesInScope(scope);
490: }
491: }
492:
493: private Enumeration doGetAttributeNamesInScope(int scope) {
494: switch (scope) {
495: case PAGE_SCOPE:
496: return attributes.keys();
497:
498: case REQUEST_SCOPE:
499: return request.getAttributeNames();
500:
501: case SESSION_SCOPE:
502: if (session == null) {
503: throw new IllegalStateException(Localizer
504: .getMessage("jsp.error.page.noSession"));
505: }
506: return session.getAttributeNames();
507:
508: case APPLICATION_SCOPE:
509: return context.getAttributeNames();
510:
511: default:
512: throw new IllegalArgumentException("Invalid scope");
513: }
514: }
515:
516: public void removeAttribute(final String name) {
517:
518: if (name == null) {
519: throw new NullPointerException(Localizer
520: .getMessage("jsp.error.attribute.null_name"));
521: }
522:
523: if (System.getSecurityManager() != null) {
524: AccessController.doPrivileged(new PrivilegedAction() {
525: public Object run() {
526: doRemoveAttribute(name);
527: return null;
528: }
529: });
530: } else {
531: doRemoveAttribute(name);
532: }
533: }
534:
535: private void doRemoveAttribute(String name) {
536: try {
537: removeAttribute(name, PAGE_SCOPE);
538: removeAttribute(name, REQUEST_SCOPE);
539: if (session != null) {
540: removeAttribute(name, SESSION_SCOPE);
541: }
542: removeAttribute(name, APPLICATION_SCOPE);
543: } catch (Exception ex) {
544: // we remove as much as we can, and
545: // simply ignore possible exceptions
546: }
547: }
548:
549: public JspWriter getOut() {
550: return out;
551: }
552:
553: public HttpSession getSession() {
554: return session;
555: }
556:
557: public Servlet getServlet() {
558: return servlet;
559: }
560:
561: public ServletConfig getServletConfig() {
562: return config;
563: }
564:
565: public ServletContext getServletContext() {
566: return config.getServletContext();
567: }
568:
569: public ServletRequest getRequest() {
570: return request;
571: }
572:
573: public ServletResponse getResponse() {
574: return response;
575: }
576:
577: public Exception getException() {
578: return (Exception) request.getAttribute(EXCEPTION);
579: }
580:
581: public Object getPage() {
582: return servlet;
583: }
584:
585: private final String getAbsolutePathRelativeToContext(
586: String relativeUrlPath) {
587: String path = relativeUrlPath;
588:
589: if (!path.startsWith("/")) {
590: String uri = (String) request
591: .getAttribute("javax.servlet.include.servlet_path");
592: if (uri == null)
593: uri = ((HttpServletRequest) request).getServletPath();
594: String baseURI = uri.substring(0, uri.lastIndexOf('/'));
595: path = baseURI + '/' + path;
596: }
597:
598: return path;
599: }
600:
601: public void include(String relativeUrlPath)
602: throws ServletException, IOException {
603: JspRuntimeLibrary.include(request, response, relativeUrlPath,
604: out, true);
605: }
606:
607: public void include(final String relativeUrlPath,
608: final boolean flush) throws ServletException, IOException {
609: if (System.getSecurityManager() != null) {
610: try {
611: AccessController
612: .doPrivileged(new PrivilegedExceptionAction() {
613: public Object run() throws Exception {
614: doInclude(relativeUrlPath, flush);
615: return null;
616: }
617: });
618: } catch (PrivilegedActionException e) {
619: Exception ex = e.getException();
620: if (ex instanceof IOException) {
621: throw (IOException) ex;
622: } else {
623: throw (ServletException) ex;
624: }
625: }
626: } else {
627: doInclude(relativeUrlPath, flush);
628: }
629: }
630:
631: private void doInclude(String relativeUrlPath, boolean flush)
632: throws ServletException, IOException {
633: JspRuntimeLibrary.include(request, response, relativeUrlPath,
634: out, flush);
635: }
636:
637: public VariableResolver getVariableResolver() {
638: return this ;
639: }
640:
641: public void forward(final String relativeUrlPath)
642: throws ServletException, IOException {
643: if (System.getSecurityManager() != null) {
644: try {
645: AccessController
646: .doPrivileged(new PrivilegedExceptionAction() {
647: public Object run() throws Exception {
648: doForward(relativeUrlPath);
649: return null;
650: }
651: });
652: } catch (PrivilegedActionException e) {
653: Exception ex = e.getException();
654: if (ex instanceof IOException) {
655: throw (IOException) ex;
656: } else {
657: throw (ServletException) ex;
658: }
659: }
660: } else {
661: doForward(relativeUrlPath);
662: }
663: }
664:
665: private void doForward(String relativeUrlPath)
666: throws ServletException, IOException {
667:
668: // JSP.4.5 If the buffer was flushed, throw IllegalStateException
669: try {
670: out.clear();
671: } catch (IOException ex) {
672: IllegalStateException ise = new IllegalStateException(
673: Localizer
674: .getMessage("jsp.error.attempt_to_clear_flushed_buffer"));
675: ise.initCause(ex);
676: throw ise;
677: }
678:
679: // Make sure that the response object is not the wrapper for include
680: while (response instanceof ServletResponseWrapperInclude) {
681: response = ((ServletResponseWrapperInclude) response)
682: .getResponse();
683: }
684:
685: final String path = getAbsolutePathRelativeToContext(relativeUrlPath);
686: String includeUri = (String) request
687: .getAttribute(Constants.INC_SERVLET_PATH);
688:
689: final ServletResponse fresponse = response;
690: final ServletRequest frequest = request;
691:
692: if (includeUri != null)
693: request.removeAttribute(Constants.INC_SERVLET_PATH);
694: try {
695: context.getRequestDispatcher(path).forward(request,
696: response);
697: } finally {
698: if (includeUri != null)
699: request.setAttribute(Constants.INC_SERVLET_PATH,
700: includeUri);
701: request.setAttribute(Constants.FORWARD_SEEN, "true");
702: }
703: }
704:
705: public BodyContent pushBody() {
706: return (BodyContent) pushBody(null);
707: }
708:
709: public JspWriter pushBody(Writer writer) {
710: depth++;
711: if (depth >= outs.length) {
712: BodyContentImpl[] newOuts = new BodyContentImpl[depth + 1];
713: for (int i = 0; i < outs.length; i++) {
714: newOuts[i] = outs[i];
715: }
716: newOuts[depth] = new BodyContentImpl(out);
717: outs = newOuts;
718: }
719:
720: outs[depth].setWriter(writer);
721: out = outs[depth];
722:
723: // Update the value of the "out" attribute in the page scope
724: // attribute namespace of this PageContext
725: setAttribute(OUT, out);
726:
727: return outs[depth];
728: }
729:
730: public JspWriter popBody() {
731: depth--;
732: if (depth >= 0) {
733: out = outs[depth];
734: } else {
735: out = baseOut;
736: }
737:
738: // Update the value of the "out" attribute in the page scope
739: // attribute namespace of this PageContext
740: setAttribute(OUT, out);
741:
742: return out;
743: }
744:
745: /**
746: * Provides programmatic access to the ExpressionEvaluator.
747: * The JSP Container must return a valid instance of an
748: * ExpressionEvaluator that can parse EL expressions.
749: */
750: public ExpressionEvaluator getExpressionEvaluator() {
751: return elExprEval;
752: }
753:
754: public void handlePageException(Exception ex) throws IOException,
755: ServletException {
756: // Should never be called since handleException() called with a
757: // Throwable in the generated servlet.
758: handlePageException((Throwable) ex);
759: }
760:
761: public void handlePageException(final Throwable t)
762: throws IOException, ServletException {
763: if (t == null)
764: throw new NullPointerException("null Throwable");
765:
766: if (System.getSecurityManager() != null) {
767: try {
768: AccessController
769: .doPrivileged(new PrivilegedExceptionAction() {
770: public Object run() throws Exception {
771: doHandlePageException(t);
772: return null;
773: }
774: });
775: } catch (PrivilegedActionException e) {
776: Exception ex = e.getException();
777: if (ex instanceof IOException) {
778: throw (IOException) ex;
779: } else {
780: throw (ServletException) ex;
781: }
782: }
783: } else {
784: doHandlePageException(t);
785: }
786:
787: }
788:
789: private void doHandlePageException(Throwable t) throws IOException,
790: ServletException {
791:
792: if (errorPageURL != null && !errorPageURL.equals("")) {
793:
794: /*
795: * Set request attributes.
796: * Do not set the javax.servlet.error.exception attribute here
797: * (instead, set in the generated servlet code for the error page)
798: * in order to prevent the ErrorReportValve, which is invoked as
799: * part of forwarding the request to the error page, from
800: * throwing it if the response has not been committed (the response
801: * will have been committed if the error page is a JSP page).
802: */
803: request.setAttribute("javax.servlet.jsp.jspException", t);
804: request
805: .setAttribute(
806: "javax.servlet.error.status_code",
807: new Integer(
808: HttpServletResponse.SC_INTERNAL_SERVER_ERROR));
809: request.setAttribute("javax.servlet.error.request_uri",
810: ((HttpServletRequest) request).getRequestURI());
811: request.setAttribute("javax.servlet.error.servlet_name",
812: config.getServletName());
813: try {
814: forward(errorPageURL);
815: } catch (IllegalStateException ise) {
816: include(errorPageURL);
817: }
818:
819: // The error page could be inside an include.
820:
821: Object newException = request
822: .getAttribute("javax.servlet.error.exception");
823:
824: // t==null means the attribute was not set.
825: if ((newException != null) && (newException == t)) {
826: request
827: .removeAttribute("javax.servlet.error.exception");
828: }
829:
830: // now clear the error code - to prevent double handling.
831: request.removeAttribute("javax.servlet.error.status_code");
832: request.removeAttribute("javax.servlet.error.request_uri");
833: request.removeAttribute("javax.servlet.error.status_code");
834: request.removeAttribute("javax.servlet.jsp.jspException");
835:
836: } else {
837: // Otherwise throw the exception wrapped inside a ServletException.
838: // Set the exception as the root cause in the ServletException
839: // to get a stack trace for the real problem
840: if (t instanceof IOException)
841: throw (IOException) t;
842: if (t instanceof ServletException)
843: throw (ServletException) t;
844: if (t instanceof RuntimeException)
845: throw (RuntimeException) t;
846:
847: Throwable rootCause = null;
848: if (t instanceof JspException) {
849: rootCause = ((JspException) t).getRootCause();
850: } else if (t instanceof ELException) {
851: rootCause = ((ELException) t).getRootCause();
852: }
853:
854: if (rootCause != null) {
855: throw new ServletException(t.getClass().getName()
856: + ": " + t.getMessage(), rootCause);
857: }
858:
859: throw new ServletException(t);
860: }
861: }
862:
863: /**
864: * VariableResolver interface
865: */
866: public Object resolveVariable(String pName) throws ELException {
867: return variableResolver.resolveVariable(pName);
868: }
869:
870: private static String XmlEscape(String s) {
871: if (s == null)
872: return null;
873: StringBuffer sb = new StringBuffer();
874: for (int i = 0; i < s.length(); i++) {
875: char c = s.charAt(i);
876: if (c == '<') {
877: sb.append("<");
878: } else if (c == '>') {
879: sb.append(">");
880: } else if (c == '\'') {
881: sb.append("'"); // '
882: } else if (c == '&') {
883: sb.append("&");
884: } else if (c == '"') {
885: sb.append("""); // "
886: } else {
887: sb.append(c);
888: }
889: }
890: return sb.toString();
891: }
892:
893: /**
894: * Proprietary method to evaluate EL expressions.
895: * XXX - This method should go away once the EL interpreter moves
896: * out of JSTL and into its own project. For now, this is necessary
897: * because the standard machinery is too slow.
898: *
899: * @param expression The expression to be evaluated
900: * @param expectedType The expected resulting type
901: * @param pageContext The page context
902: * @param functionMap Maps prefix and name to Method
903: * @return The result of the evaluation
904: */
905: public static Object proprietaryEvaluate(final String expression,
906: final Class expectedType, final PageContext pageContext,
907: final ProtectedFunctionMapper functionMap,
908: final boolean escape) throws ELException {
909: Object retValue;
910: if (System.getSecurityManager() != null) {
911: try {
912: retValue = AccessController
913: .doPrivileged(new PrivilegedExceptionAction() {
914:
915: public Object run() throws Exception {
916: return elExprEval.evaluate(expression,
917: expectedType, pageContext
918: .getVariableResolver(),
919: functionMap);
920: }
921: });
922: } catch (PrivilegedActionException ex) {
923: Exception realEx = ex.getException();
924: if (realEx instanceof ELException) {
925: throw (ELException) realEx;
926: } else {
927: throw new ELException(realEx);
928: }
929: }
930: } else {
931: retValue = elExprEval.evaluate(expression, expectedType,
932: pageContext.getVariableResolver(), functionMap);
933: }
934: if (escape) {
935: retValue = XmlEscape(retValue.toString());
936: }
937:
938: return retValue;
939: }
940:
941: }
|