/* | |
* Licensed to the Apache Software Foundation (ASF) under one or more | |
* contributor license agreements. See the NOTICE file distributed with | |
* this work for additional information regarding copyright ownership. | |
* The ASF licenses this file to You under the Apache License, Version 2.0 | |
* (the "License"); you may not use this file except in compliance with | |
* the License. You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
package org.apache.struts2.jasper.runtime; | |
import org.apache.commons.el.ExpressionEvaluatorImpl; | |
import org.apache.commons.el.VariableResolverImpl; | |
import org.apache.struts2.jasper.Constants; | |
import org.apache.struts2.jasper.compiler.Localizer; | |
import org.apache.struts2.jasper.security.SecurityUtil; | |
import javax.servlet.*; | |
import javax.servlet.http.HttpServletRequest; | |
import javax.servlet.http.HttpServletResponse; | |
import javax.servlet.http.HttpSession; | |
import javax.servlet.jsp.JspException; | |
import javax.servlet.jsp.JspFactory; | |
import javax.servlet.jsp.JspWriter; | |
import javax.servlet.jsp.PageContext; | |
import javax.servlet.jsp.el.ELException; | |
import javax.servlet.jsp.el.ExpressionEvaluator; | |
import javax.servlet.jsp.el.VariableResolver; | |
import javax.servlet.jsp.tagext.BodyContent; | |
import java.io.IOException; | |
import java.io.Writer; | |
import java.security.AccessController; | |
import java.security.PrivilegedAction; | |
import java.security.PrivilegedActionException; | |
import java.security.PrivilegedExceptionAction; | |
import java.util.Enumeration; | |
import java.util.Hashtable; | |
/** | |
* Implementation of the PageContext class from the JSP spec. | |
* Also doubles as a VariableResolver for the EL. | |
* | |
* @author Anil K. Vijendran | |
* @author Larry Cable | |
* @author Hans Bergsten | |
* @author Pierre Delisle | |
* @author Mark Roth | |
* @author Jan Luehe | |
*/ | |
public class PageContextImpl extends PageContext implements VariableResolver { | |
// The expression evaluator, for evaluating EL expressions. | |
private static ExpressionEvaluatorImpl elExprEval | |
= new ExpressionEvaluatorImpl(false); | |
// The variable resolver, for evaluating EL expressions. | |
private VariableResolverImpl variableResolver; | |
private BodyContentImpl[] outs; | |
private int depth; | |
// per-servlet state | |
private Servlet servlet; | |
private ServletConfig config; | |
private ServletContext context; | |
private String errorPageURL; | |
// page-scope attributes | |
private transient Hashtable attributes; | |
// per-request state | |
private transient ServletRequest request; | |
private transient ServletResponse response; | |
private transient HttpSession session; | |
private boolean isIncluded; | |
// initial output stream | |
private transient JspWriter out; | |
private transient JspWriterImpl baseOut; | |
/* | |
* Constructor. | |
*/ | |
PageContextImpl(JspFactory factory) { | |
this.variableResolver = new VariableResolverImpl(this); | |
this.outs = new BodyContentImpl[0]; | |
this.attributes = new Hashtable(16); | |
this.depth = -1; | |
} | |
public void initialize(Servlet servlet, | |
ServletRequest request, | |
ServletResponse response, | |
String errorPageURL, | |
boolean needsSession, | |
int bufferSize, | |
boolean autoFlush) throws IOException { | |
_initialize(servlet, request, response, errorPageURL, needsSession, | |
bufferSize, autoFlush); | |
} | |
private void _initialize(Servlet servlet, | |
ServletRequest request, | |
ServletResponse response, | |
String errorPageURL, | |
boolean needsSession, | |
int bufferSize, | |
boolean autoFlush) throws IOException { | |
// initialize state | |
this.servlet = servlet; | |
this.config = servlet.getServletConfig(); | |
this.context = config.getServletContext(); | |
this.errorPageURL = errorPageURL; | |
this.request = request; | |
this.response = response; | |
// Setup session (if required) | |
if (request instanceof HttpServletRequest && needsSession) | |
this.session = ((HttpServletRequest)request).getSession(); | |
if (needsSession && session == null) | |
throw new IllegalStateException | |
("Page needs a session and none is available"); | |
// initialize the initial out ... | |
depth = -1; | |
if (this.baseOut == null) { | |
this.baseOut = new JspWriterImpl(response, bufferSize, autoFlush); | |
} else { | |
this.baseOut.init(response, bufferSize, autoFlush); | |
} | |
this.out = baseOut; | |
// register names/values as per spec | |
setAttribute(OUT, this.out); | |
setAttribute(REQUEST, request); | |
setAttribute(RESPONSE, response); | |
if (session != null) | |
setAttribute(SESSION, session); | |
setAttribute(PAGE, servlet); | |
setAttribute(CONFIG, config); | |
setAttribute(PAGECONTEXT, this); | |
setAttribute(APPLICATION, context); | |
isIncluded = request.getAttribute( | |
"javax.servlet.include.servlet_path") != null; | |
} | |
public void release() { | |
out = baseOut; | |
try { | |
if (isIncluded) { | |
((JspWriterImpl)out).flushBuffer(); | |
// push it into the including jspWriter | |
} else { | |
// Old code: | |
//out.flush(); | |
// Do not flush the buffer even if we're not included (i.e. | |
// we are the main page. The servlet will flush it and close | |
// the stream. | |
((JspWriterImpl)out).flushBuffer(); | |
} | |
} catch (IOException ex) { | |
context.log( | |
"PageContextImpl.release(): Internal error flushing buffer"); | |
} | |
servlet = null; | |
config = null; | |
context = null; | |
errorPageURL = null; | |
request = null; | |
response = null; | |
depth = -1; | |
baseOut.recycle(); | |
session = null; | |
attributes.clear(); | |
} | |
public Object getAttribute(final String name) { | |
if (name == null) { | |
throw new NullPointerException( | |
Localizer.getMessage("jsp.error.attribute.null_name")); | |
} | |
if (SecurityUtil.isPackageProtectionEnabled()){ | |
return AccessController.doPrivileged(new PrivilegedAction(){ | |
public Object run(){ | |
return doGetAttribute(name); | |
} | |
}); | |
} else { | |
return doGetAttribute(name); | |
} | |
} | |
private Object doGetAttribute(String name){ | |
return attributes.get(name); | |
} | |
public Object getAttribute(final String name, final int scope) { | |
if (name == null) { | |
throw new NullPointerException( | |
Localizer.getMessage("jsp.error.attribute.null_name")); | |
} | |
if (SecurityUtil.isPackageProtectionEnabled()){ | |
return AccessController.doPrivileged(new PrivilegedAction(){ | |
public Object run(){ | |
return doGetAttribute(name, scope); | |
} | |
}); | |
} else { | |
return doGetAttribute(name, scope); | |
} | |
} | |
private Object doGetAttribute(String name, int scope){ | |
switch (scope) { | |
case PAGE_SCOPE: | |
return attributes.get(name); | |
case REQUEST_SCOPE: | |
return request.getAttribute(name); | |
case SESSION_SCOPE: | |
if (session == null) { | |
throw new IllegalStateException( | |
Localizer.getMessage("jsp.error.page.noSession")); | |
} | |
return session.getAttribute(name); | |
case APPLICATION_SCOPE: | |
return context.getAttribute(name); | |
default: | |
throw new IllegalArgumentException("Invalid scope"); | |
} | |
} | |
public void setAttribute(final String name, final Object attribute) { | |
if (name == null) { | |
throw new NullPointerException( | |
Localizer.getMessage("jsp.error.attribute.null_name")); | |
} | |
if (SecurityUtil.isPackageProtectionEnabled()){ | |
AccessController.doPrivileged(new PrivilegedAction(){ | |
public Object run(){ | |
doSetAttribute(name, attribute); | |
return null; | |
} | |
}); | |
} else { | |
doSetAttribute(name, attribute); | |
} | |
} | |
private void doSetAttribute(String name, Object attribute){ | |
if (attribute != null) { | |
attributes.put(name, attribute); | |
} else { | |
removeAttribute(name, PAGE_SCOPE); | |
} | |
} | |
public void setAttribute(final String name, final Object o, final int scope) { | |
if (name == null) { | |
throw new NullPointerException( | |
Localizer.getMessage("jsp.error.attribute.null_name")); | |
} | |
if (SecurityUtil.isPackageProtectionEnabled()){ | |
AccessController.doPrivileged(new PrivilegedAction(){ | |
public Object run(){ | |
doSetAttribute(name, o, scope); | |
return null; | |
} | |
}); | |
} else { | |
doSetAttribute(name, o, scope); | |
} | |
} | |
private void doSetAttribute(String name, Object o, int scope ){ | |
if (o != null) { | |
switch (scope) { | |
case PAGE_SCOPE: | |
attributes.put(name, o); | |
break; | |
case REQUEST_SCOPE: | |
request.setAttribute(name, o); | |
break; | |
case SESSION_SCOPE: | |
if (session == null) { | |
throw new IllegalStateException( | |
Localizer.getMessage("jsp.error.page.noSession")); | |
} | |
session.setAttribute(name, o); | |
break; | |
case APPLICATION_SCOPE: | |
context.setAttribute(name, o); | |
break; | |
default: | |
throw new IllegalArgumentException("Invalid scope"); | |
} | |
} else { | |
removeAttribute(name, scope); | |
} | |
} | |
public void removeAttribute(final String name, final int scope) { | |
if (name == null) { | |
throw new NullPointerException( | |
Localizer.getMessage("jsp.error.attribute.null_name")); | |
} | |
if (SecurityUtil.isPackageProtectionEnabled()){ | |
AccessController.doPrivileged(new PrivilegedAction(){ | |
public Object run(){ | |
doRemoveAttribute(name, scope); | |
return null; | |
} | |
}); | |
} else { | |
doRemoveAttribute(name, scope); | |
} | |
} | |
private void doRemoveAttribute(String name, int scope){ | |
switch (scope) { | |
case PAGE_SCOPE: | |
attributes.remove(name); | |
break; | |
case REQUEST_SCOPE: | |
request.removeAttribute(name); | |
break; | |
case SESSION_SCOPE: | |
if (session == null) { | |
throw new IllegalStateException( | |
Localizer.getMessage("jsp.error.page.noSession")); | |
} | |
session.removeAttribute(name); | |
break; | |
case APPLICATION_SCOPE: | |
context.removeAttribute(name); | |
break; | |
default: | |
throw new IllegalArgumentException("Invalid scope"); | |
} | |
} | |
public int getAttributesScope(final String name) { | |
if (name == null) { | |
throw new NullPointerException( | |
Localizer.getMessage("jsp.error.attribute.null_name")); | |
} | |
if (SecurityUtil.isPackageProtectionEnabled()){ | |
return ((Integer)AccessController.doPrivileged(new PrivilegedAction(){ | |
public Object run(){ | |
return new Integer(doGetAttributeScope(name)); | |
} | |
})).intValue(); | |
} else { | |
return doGetAttributeScope(name); | |
} | |
} | |
private int doGetAttributeScope(String name){ | |
if (attributes.get(name) != null) | |
return PAGE_SCOPE; | |
if (request.getAttribute(name) != null) | |
return REQUEST_SCOPE; | |
if (session != null) { | |
try { | |
if (session.getAttribute(name) != null) | |
return SESSION_SCOPE; | |
} catch(IllegalStateException ise) { | |
// Session has been invalidated. | |
// Ignore and fall through to application scope. | |
} | |
} | |
if (context.getAttribute(name) != null) | |
return APPLICATION_SCOPE; | |
return 0; | |
} | |
public Object findAttribute(final String name) { | |
if (SecurityUtil.isPackageProtectionEnabled()){ | |
return AccessController.doPrivileged(new PrivilegedAction(){ | |
public Object run(){ | |
if (name == null) { | |
throw new NullPointerException( | |
Localizer.getMessage("jsp.error.attribute.null_name")); | |
} | |
return doFindAttribute(name); | |
} | |
}); | |
} else { | |
if (name == null) { | |
throw new NullPointerException( | |
Localizer.getMessage("jsp.error.attribute.null_name")); | |
} | |
return doFindAttribute(name); | |
} | |
} | |
private Object doFindAttribute(String name){ | |
Object o = attributes.get(name); | |
if (o != null) | |
return o; | |
o = request.getAttribute(name); | |
if (o != null) | |
return o; | |
if (session != null) { | |
try { | |
o = session.getAttribute(name); | |
} catch(IllegalStateException ise) { | |
// Session has been invalidated. | |
// Ignore and fall through to application scope. | |
} | |
if (o != null) | |
return o; | |
} | |
return context.getAttribute(name); | |
} | |
public Enumeration getAttributeNamesInScope(final int scope) { | |
if (SecurityUtil.isPackageProtectionEnabled()){ | |
return (Enumeration) | |
AccessController.doPrivileged(new PrivilegedAction(){ | |
public Object run(){ | |
return doGetAttributeNamesInScope(scope); | |
} | |
}); | |
} else { | |
return doGetAttributeNamesInScope(scope); | |
} | |
} | |
private Enumeration doGetAttributeNamesInScope(int scope){ | |
switch (scope) { | |
case PAGE_SCOPE: | |
return attributes.keys(); | |
case REQUEST_SCOPE: | |
return request.getAttributeNames(); | |
case SESSION_SCOPE: | |
if (session == null) { | |
throw new IllegalStateException( | |
Localizer.getMessage("jsp.error.page.noSession")); | |
} | |
return session.getAttributeNames(); | |
case APPLICATION_SCOPE: | |
return context.getAttributeNames(); | |
default: | |
throw new IllegalArgumentException("Invalid scope"); | |
} | |
} | |
public void removeAttribute(final String name) { | |
if (name == null) { | |
throw new NullPointerException( | |
Localizer.getMessage("jsp.error.attribute.null_name")); | |
} | |
if (SecurityUtil.isPackageProtectionEnabled()){ | |
AccessController.doPrivileged(new PrivilegedAction(){ | |
public Object run(){ | |
doRemoveAttribute(name); | |
return null; | |
} | |
}); | |
} else { | |
doRemoveAttribute(name); | |
} | |
} | |
private void doRemoveAttribute(String name){ | |
removeAttribute(name, PAGE_SCOPE); | |
removeAttribute(name, REQUEST_SCOPE); | |
if( session != null ) { | |
try { | |
removeAttribute(name, SESSION_SCOPE); | |
} catch(IllegalStateException ise) { | |
// Session has been invalidated. | |
// Ignore and fall throw to application scope. | |
} | |
} | |
removeAttribute(name, APPLICATION_SCOPE); | |
} | |
public JspWriter getOut() { | |
return out; | |
} | |
public HttpSession getSession() { return session; } | |
public Servlet getServlet() { return servlet; } | |
public ServletConfig getServletConfig() { return config; } | |
public ServletContext getServletContext() { | |
return config.getServletContext(); | |
} | |
public ServletRequest getRequest() { return request; } | |
public ServletResponse getResponse() { return response; } | |
/** | |
* Returns the exception associated with this page | |
* context, if any. | |
* <p/> | |
* Added wrapping for Throwables to avoid ClassCastException: | |
* see Bugzilla 31171 for details. | |
* | |
* @return The Exception associated with this page context, if any. | |
*/ | |
public Exception getException() { | |
Throwable t = JspRuntimeLibrary.getThrowable(request); | |
// Only wrap if needed | |
if((t != null) && (! (t instanceof Exception))) { | |
t = new JspException(t); | |
} | |
return (Exception) t; | |
} | |
public Object getPage() { return servlet; } | |
private final String getAbsolutePathRelativeToContext(String relativeUrlPath) { | |
String path = relativeUrlPath; | |
if (!path.startsWith("/")) { | |
String uri = (String) | |
request.getAttribute("javax.servlet.include.servlet_path"); | |
if (uri == null) | |
uri = ((HttpServletRequest) request).getServletPath(); | |
String baseURI = uri.substring(0, uri.lastIndexOf('/')); | |
path = baseURI+'/'+path; | |
} | |
return path; | |
} | |
public void include(String relativeUrlPath) | |
throws ServletException, IOException { | |
JspRuntimeLibrary.include(request, response, relativeUrlPath, out, | |
true); | |
} | |
public void include(final String relativeUrlPath, final boolean flush) | |
throws ServletException, IOException { | |
if (SecurityUtil.isPackageProtectionEnabled()){ | |
try{ | |
AccessController.doPrivileged(new PrivilegedExceptionAction(){ | |
public Object run() throws Exception{ | |
doInclude(relativeUrlPath, flush); | |
return null; | |
} | |
}); | |
} catch (PrivilegedActionException e){ | |
Exception ex = e.getException(); | |
if (ex instanceof IOException){ | |
throw (IOException)ex; | |
} else { | |
throw (ServletException)ex; | |
} | |
} | |
} else { | |
doInclude(relativeUrlPath, flush); | |
} | |
} | |
private void doInclude(String relativeUrlPath, boolean flush) | |
throws ServletException, IOException { | |
JspRuntimeLibrary.include(request, response, relativeUrlPath, out, | |
flush); | |
} | |
public VariableResolver getVariableResolver() { | |
return this; | |
} | |
public void forward(final String relativeUrlPath) | |
throws ServletException, IOException { | |
if (SecurityUtil.isPackageProtectionEnabled()){ | |
try{ | |
AccessController.doPrivileged(new PrivilegedExceptionAction(){ | |
public Object run() throws Exception{ | |
doForward(relativeUrlPath); | |
return null; | |
} | |
}); | |
} catch (PrivilegedActionException e){ | |
Exception ex = e.getException(); | |
if (ex instanceof IOException){ | |
throw (IOException)ex; | |
} else { | |
throw (ServletException)ex; | |
} | |
} | |
} else { | |
doForward(relativeUrlPath); | |
} | |
} | |
private void doForward(String relativeUrlPath) | |
throws ServletException, IOException{ | |
// JSP.4.5 If the buffer was flushed, throw IllegalStateException | |
try { | |
out.clear(); | |
} catch (IOException ex) { | |
IllegalStateException ise = | |
new IllegalStateException(Localizer.getMessage( | |
"jsp.error.attempt_to_clear_flushed_buffer")); | |
ise.initCause(ex); | |
throw ise; | |
} | |
// Make sure that the response object is not the wrapper for include | |
while (response instanceof ServletResponseWrapperInclude) { | |
response = ((ServletResponseWrapperInclude)response).getResponse(); | |
} | |
final String path = getAbsolutePathRelativeToContext(relativeUrlPath); | |
String includeUri | |
= (String) request.getAttribute(Constants.INC_SERVLET_PATH); | |
if (includeUri != null) | |
request.removeAttribute(Constants.INC_SERVLET_PATH); | |
try { | |
context.getRequestDispatcher(path).forward(request, response); | |
} finally { | |
if (includeUri != null) | |
request.setAttribute(Constants.INC_SERVLET_PATH, includeUri); | |
request.setAttribute(Constants.FORWARD_SEEN, "true"); | |
} | |
} | |
public BodyContent pushBody() { | |
return (BodyContent) pushBody(null); | |
} | |
public JspWriter pushBody(Writer writer) { | |
depth++; | |
if (depth >= outs.length) { | |
BodyContentImpl[] newOuts = new BodyContentImpl[depth + 1]; | |
for (int i=0; i<outs.length; i++) { | |
newOuts[i] = outs[i]; | |
} | |
newOuts[depth] = new BodyContentImpl(out); | |
outs = newOuts; | |
} | |
outs[depth].setWriter(writer); | |
out = outs[depth]; | |
// Update the value of the "out" attribute in the page scope | |
// attribute namespace of this PageContext | |
setAttribute(OUT, out); | |
return outs[depth]; | |
} | |
public JspWriter popBody() { | |
depth--; | |
if (depth >= 0) { | |
out = outs[depth]; | |
} else { | |
out = baseOut; | |
} | |
// Update the value of the "out" attribute in the page scope | |
// attribute namespace of this PageContext | |
setAttribute(OUT, out); | |
return out; | |
} | |
/** | |
* Provides programmatic access to the ExpressionEvaluator. | |
* The JSP Container must return a valid instance of an | |
* ExpressionEvaluator that can parse EL expressions. | |
*/ | |
public ExpressionEvaluator getExpressionEvaluator() { | |
return elExprEval; | |
} | |
public void handlePageException(Exception ex) | |
throws IOException, ServletException | |
{ | |
// Should never be called since handleException() called with a | |
// Throwable in the generated servlet. | |
handlePageException((Throwable) ex); | |
} | |
public void handlePageException(final Throwable t) | |
throws IOException, ServletException | |
{ | |
if (t == null) | |
throw new NullPointerException("null Throwable"); | |
if (SecurityUtil.isPackageProtectionEnabled()){ | |
try{ | |
AccessController.doPrivileged(new PrivilegedExceptionAction(){ | |
public Object run() throws Exception{ | |
doHandlePageException(t); | |
return null; | |
} | |
}); | |
} catch (PrivilegedActionException e){ | |
Exception ex = e.getException(); | |
if (ex instanceof IOException){ | |
throw (IOException)ex; | |
} else { | |
throw (ServletException)ex; | |
} | |
} | |
} else { | |
doHandlePageException(t); | |
} | |
} | |
private void doHandlePageException(Throwable t) | |
throws IOException, ServletException { | |
if (errorPageURL != null && !errorPageURL.equals("")) { | |
/* | |
* Set request attributes. | |
* Do not set the javax.servlet.error.exception attribute here | |
* (instead, set in the generated servlet code for the error page) | |
* in order to prevent the ErrorReportValve, which is invoked as | |
* part of forwarding the request to the error page, from | |
* throwing it if the response has not been committed (the response | |
* will have been committed if the error page is a JSP page). | |
*/ | |
request.setAttribute("javax.servlet.jsp.jspException", t); | |
request.setAttribute("javax.servlet.error.status_code", | |
new Integer(HttpServletResponse.SC_INTERNAL_SERVER_ERROR)); | |
request.setAttribute("javax.servlet.error.request_uri", | |
((HttpServletRequest) request).getRequestURI()); | |
request.setAttribute("javax.servlet.error.servlet_name", | |
config.getServletName()); | |
try { | |
forward(errorPageURL); | |
} catch (IllegalStateException ise) { | |
include(errorPageURL); | |
} | |
// The error page could be inside an include. | |
Object newException = request.getAttribute("javax.servlet.error.exception"); | |
// t==null means the attribute was not set. | |
if( (newException!= null) && (newException==t) ) { | |
request.removeAttribute("javax.servlet.error.exception"); | |
} | |
// now clear the error code - to prevent double handling. | |
request.removeAttribute("javax.servlet.error.status_code"); | |
request.removeAttribute("javax.servlet.error.request_uri"); | |
request.removeAttribute("javax.servlet.error.status_code"); | |
request.removeAttribute("javax.servlet.jsp.jspException"); | |
} else { | |
// Otherwise throw the exception wrapped inside a ServletException. | |
// Set the exception as the root cause in the ServletException | |
// to get a stack trace for the real problem | |
if (t instanceof IOException) throw (IOException)t; | |
if (t instanceof ServletException) throw (ServletException)t; | |
if (t instanceof RuntimeException) throw (RuntimeException)t; | |
Throwable rootCause = null; | |
if (t instanceof JspException) { | |
rootCause = ((JspException) t).getRootCause(); | |
} else if (t instanceof ELException) { | |
rootCause = ((ELException) t).getRootCause(); | |
} | |
if (rootCause != null) { | |
throw new ServletException(t.getClass().getName() + ": " + | |
t.getMessage(), rootCause); | |
} | |
throw new ServletException(t); | |
} | |
} | |
/** | |
* VariableResolver interface | |
*/ | |
public Object resolveVariable(String pName) throws ELException { | |
return variableResolver.resolveVariable(pName); | |
} | |
/** | |
* XML-escape the given string. | |
* | |
* @param s The string to escape | |
* @return The escape string | |
*/ | |
private static String XmlEscape(String s) { | |
if (s == null) { | |
return null; | |
} | |
StringBuffer sb = new StringBuffer(); | |
for(int i = 0; i < s.length(); i++) { | |
char c = s.charAt(i); | |
if (c == '<') { | |
sb.append("<"); | |
} else if (c == '>') { | |
sb.append(">"); | |
} else if (c == '\'') { | |
sb.append("'"); // ' | |
} else if (c == '&') { | |
sb.append("&"); | |
} else if (c == '"') { | |
sb.append("""); // " | |
} else { | |
sb.append(c); | |
} | |
} | |
return sb.toString(); | |
} | |
/** | |
* Proprietary method to evaluate EL expressions. | |
* XXX - This method should go away once the EL interpreter moves | |
* out of JSTL and into its own project. For now, this is necessary | |
* because the standard machinery is too slow. | |
* | |
* @param expression The expression to be evaluated | |
* @param expectedType The expected resulting type | |
* @param pageContext The page context | |
* @param functionMap Maps prefix and name to Method | |
* @return The result of the evaluation | |
*/ | |
public static Object proprietaryEvaluate(final String expression, | |
final Class expectedType, | |
final PageContext pageContext, | |
final ProtectedFunctionMapper functionMap, | |
final boolean escape) | |
throws ELException | |
{ | |
Object retValue; | |
if (SecurityUtil.isPackageProtectionEnabled()){ | |
try { | |
retValue = AccessController.doPrivileged( | |
new PrivilegedExceptionAction(){ | |
public Object run() throws Exception{ | |
return elExprEval.evaluate(expression, | |
expectedType, | |
pageContext.getVariableResolver(), | |
functionMap); | |
} | |
}); | |
} catch (PrivilegedActionException ex) { | |
Exception realEx = ex.getException(); | |
if (realEx instanceof ELException) { | |
throw (ELException) realEx; | |
} else { | |
throw new ELException(realEx); | |
} | |
} | |
} else { | |
retValue = elExprEval.evaluate(expression, | |
expectedType, | |
pageContext.getVariableResolver(), | |
functionMap); | |
} | |
if (escape) { | |
retValue = XmlEscape(retValue.toString()); | |
} | |
return retValue; | |
} | |
} |