/* * 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.jasper.runtime;
/** * Bunch of util methods that are used by code generated for useBean, * getProperty and setProperty. * * The __begin, __end stuff is there so that the JSP engine can * actually parse this file and inline them if people don't want * runtime dependencies on this class. However, I'm not sure if that * works so well right now. It got forgotten at some point. -akv * * @author Mandar Raje * @author Shawn Bayern
*/ publicclass JspRuntimeLibrary {
publicstaticfinalboolean GRAAL;
static { boolean result = false; try { Class<?> nativeImageClazz = Class.forName("org.graalvm.nativeimage.ImageInfo");
result = nativeImageClazz.getMethod("inImageCode").invoke(null) != null; // Note: This will also be true for the Graal substrate VM
} catch (ClassNotFoundException e) { // Must be Graal
} catch (ReflectiveOperationException | IllegalArgumentException e) { // Should never happen
}
GRAAL = result || System.getProperty("org.graalvm.nativeimage.imagecode") != null;
}
/** * Returns the value of the jakarta.servlet.error.exception request * attribute value, if present, otherwise the value of the * jakarta.servlet.jsp.jspException request attribute value. * * This method is called at the beginning of the generated servlet code * for a JSP error page, when the "exception" implicit scripting language * variable is initialized. * @param request The Servlet request * @return the throwable in the error attribute if any
*/ publicstatic Throwable getThrowable(ServletRequest request) {
Throwable error = (Throwable) request.getAttribute(
RequestDispatcher.ERROR_EXCEPTION); if (error == null) {
error = (Throwable) request.getAttribute(PageContext.EXCEPTION); if (error != null) { /* * The only place that sets JSP_EXCEPTION is * PageContextImpl.handlePageException(). It really should set * SERVLET_EXCEPTION, but that would interfere with the * ErrorReportValve. Therefore, if JSP_EXCEPTION is set, we * need to set SERVLET_EXCEPTION.
*/
request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, error);
}
}
return error;
}
publicstaticboolean coerceToBoolean(String s) { if (s == null || s.length() == 0) { returnfalse;
} else { returnBoolean.parseBoolean(s);
}
}
/** * Create a typed array. * This is a special case where params are passed through * the request and the property is indexed. * @param propertyName The property name * @param bean The bean * @param method The method * @param values Array values * @param t The class * @param propertyEditorClass The editor for the property * @throws JasperException An error occurred
*/ publicstaticvoid createTypedArray(String propertyName,
Object bean,
Method method,
String[] values, Class<?> t, Class<?> propertyEditorClass) throws JasperException {
try { if (propertyEditorClass != null) {
Object[] tmpval = new Integer[values.length]; for (int i=0; i<values.length; i++) {
tmpval[i] = getValueFromBeanInfoPropertyEditor(
t, propertyName, values[i], propertyEditorClass);
}
method.invoke (bean, new Object[] {tmpval});
} elseif (t.equals(Integer.class)) {
Integer []tmpval = new Integer[values.length]; for (int i = 0 ; i < values.length; i++) {
tmpval[i] = Integer.valueOf(values[i]);
}
method.invoke (bean, new Object[] {tmpval});
} elseif (t.equals(Byte.class)) { Byte[] tmpval = newByte[values.length]; for (int i = 0 ; i < values.length; i++) {
tmpval[i] = Byte.valueOf(values[i]);
}
method.invoke (bean, new Object[] {tmpval});
} elseif (t.equals(Boolean.class)) { Boolean[] tmpval = newBoolean[values.length]; for (int i = 0 ; i < values.length; i++) {
tmpval[i] = Boolean.valueOf(values[i]);
}
method.invoke (bean, new Object[] {tmpval});
} elseif (t.equals(Short.class)) { Short[] tmpval = newShort[values.length]; for (int i = 0 ; i < values.length; i++) {
tmpval[i] = Short.valueOf(values[i]);
}
method.invoke (bean, new Object[] {tmpval});
} elseif (t.equals(Long.class)) { Long[] tmpval = newLong[values.length]; for (int i = 0 ; i < values.length; i++) {
tmpval[i] = Long.valueOf(values[i]);
}
method.invoke (bean, new Object[] {tmpval});
} elseif (t.equals(Double.class)) { Double[] tmpval = newDouble[values.length]; for (int i = 0 ; i < values.length; i++) {
tmpval[i] = Double.valueOf(values[i]);
}
method.invoke (bean, new Object[] {tmpval});
} elseif (t.equals(Float.class)) { Float[] tmpval = newFloat[values.length]; for (int i = 0 ; i < values.length; i++) {
tmpval[i] = Float.valueOf(values[i]);
}
method.invoke (bean, new Object[] {tmpval});
} elseif (t.equals(Character.class)) {
Character[] tmpval = new Character[values.length]; for (int i = 0 ; i < values.length; i++) {
tmpval[i] = Character.valueOf(values[i].charAt(0));
}
method.invoke (bean, new Object[] {tmpval});
} elseif (t.equals(int.class)) { int []tmpval = newint[values.length]; for (int i = 0 ; i < values.length; i++) {
tmpval[i] = Integer.parseInt (values[i]);
}
method.invoke (bean, new Object[] {tmpval});
} elseif (t.equals(byte.class)) { byte[] tmpval = newbyte[values.length]; for (int i = 0 ; i < values.length; i++) {
tmpval[i] = Byte.parseByte (values[i]);
}
method.invoke (bean, new Object[] {tmpval});
} elseif (t.equals(boolean.class)) { boolean[] tmpval = newboolean[values.length]; for (int i = 0 ; i < values.length; i++) {
tmpval[i] = Boolean.parseBoolean(values[i]);
}
method.invoke (bean, new Object[] {tmpval});
} elseif (t.equals(short.class)) { short[] tmpval = newshort[values.length]; for (int i = 0 ; i < values.length; i++) {
tmpval[i] = Short.parseShort (values[i]);
}
method.invoke (bean, new Object[] {tmpval});
} elseif (t.equals(long.class)) { long[] tmpval = newlong[values.length]; for (int i = 0 ; i < values.length; i++) {
tmpval[i] = Long.parseLong (values[i]);
}
method.invoke (bean, new Object[] {tmpval});
} elseif (t.equals(double.class)) { double[] tmpval = newdouble[values.length]; for (int i = 0 ; i < values.length; i++) {
tmpval[i] = Double.parseDouble(values[i]);
}
method.invoke (bean, new Object[] {tmpval});
} elseif (t.equals(float.class)) { float[] tmpval = newfloat[values.length]; for (int i = 0 ; i < values.length; i++) {
tmpval[i] = Float.parseFloat(values[i]);
}
method.invoke (bean, new Object[] {tmpval});
} elseif (t.equals(char.class)) { char[] tmpval = newchar[values.length]; for (int i = 0 ; i < values.length; i++) {
tmpval[i] = values[i].charAt(0);
}
method.invoke (bean, new Object[] {tmpval});
} else {
Object[] tmpval = new Integer[values.length]; for (int i=0; i<values.length; i++) {
tmpval[i] =
getValueFromPropertyEditorManager(
t, propertyName, values[i]);
}
method.invoke (bean, new Object[] {tmpval});
}
} catch (RuntimeException | ReflectiveOperationException ex) {
Throwable thr = ExceptionUtils.unwrapInvocationTargetException(ex);
ExceptionUtils.handleThrowable(thr); thrownew JasperException ("error in invoking method", ex);
}
}
/** * Escape special shell characters. * @param unescString The string to shell-escape * @return The escaped shell string.
*/ publicstatic String escapeQueryString(String unescString) { if (unescString == null) { returnnull;
}
StringBuilder escStringBuilder = new StringBuilder();
String shellSpChars = "&;`'\"|*?~<>^()[]{}$\\\n";
for (int index = 0; index < unescString.length(); index++) { char nextChar = unescString.charAt(index);
if (shellSpChars.indexOf(nextChar) != -1) {
escStringBuilder.append('\\');
}
// ************************************************************************ // General Purpose Runtime Methods // ************************************************************************
/** * Convert a possibly relative resource path into a context-relative * resource path that starts with a '/'. * * @param request The servlet request we are processing * @param relativePath The possibly relative resource path * @return an absolute path
*/ publicstatic String getContextRelativePath(ServletRequest request,
String relativePath) {
if (relativePath.startsWith("/")) { return relativePath;
} if (!(request instanceof HttpServletRequest)) { return relativePath;
}
HttpServletRequest hrequest = (HttpServletRequest) request;
String uri = (String) request.getAttribute(
RequestDispatcher.INCLUDE_SERVLET_PATH); if (uri != null) {
String pathInfo = (String)
request.getAttribute(RequestDispatcher.INCLUDE_PATH_INFO); if (pathInfo == null) { if (uri.lastIndexOf('/') >= 0) {
uri = uri.substring(0, uri.lastIndexOf('/'));
}
}
} else {
uri = hrequest.getServletPath(); if (uri.lastIndexOf('/') >= 0) {
uri = uri.substring(0, uri.lastIndexOf('/'));
}
} return uri + '/' + relativePath;
}
/** * Perform a RequestDispatcher.include() operation, with optional flushing * of the response beforehand. * * @param request The servlet request we are processing * @param response The servlet response we are processing * @param relativePath The relative path of the resource to be included * @param out The Writer to whom we are currently writing * @param flush Should we flush before the include is processed? * * @exception IOException if thrown by the included servlet * @exception ServletException if thrown by the included servlet
*/ publicstaticvoid include(ServletRequest request,
ServletResponse response,
String relativePath,
JspWriter out, boolean flush) throws IOException, ServletException {
if (flush && !(out instanceof BodyContent)) {
out.flush();
}
// FIXME - It is tempting to use request.getRequestDispatcher() to // resolve a relative path directly, but Catalina currently does not // take into account whether the caller is inside a RequestDispatcher // include or not. Whether Catalina *should* take that into account // is a spec issue currently under review. In the mean time, // replicate Jasper's previous behavior
/** * URL encodes a string, based on the supplied character encoding. * This performs the same function as java.next.URLEncode.encode * in J2SDK1.4, and should be removed if the only platform supported * is 1.4 or higher. * @param s The String to be URL encoded. * @param enc The character encoding * @return The URL encoded String
*/ publicstatic String URLEncode(String s, String enc) {
if (s == null) { return"null";
}
if (enc == null) {
enc = "ISO-8859-1"; // The default request encoding
}
StringBuilder out = new StringBuilder(s.length());
ByteArrayOutputStream buf = new ByteArrayOutputStream();
OutputStreamWriter writer = null; try {
writer = new OutputStreamWriter(buf, enc);
} catch (java.io.UnsupportedEncodingException ex) { // Use the default encoding?
writer = new OutputStreamWriter(buf);
}
for (int i = 0; i < s.length(); i++) { int c = s.charAt(i); if (c == ' ') {
out.append('+');
} elseif (isSafeChar(c)) {
out.append((char)c);
} else { // convert to external encoding before hex conversion try {
writer.write(c);
writer.flush();
} catch(IOException e) {
buf.reset(); continue;
} byte[] ba = buf.toByteArray(); for (byte b : ba) {
out.append('%'); // Converting each byte in the buffer
out.append(Character.forDigit((b >> 4) & 0xf, 16));
out.append(Character.forDigit(b & 0xf, 16));
}
buf.reset();
}
} return out.toString();
}
privatestaticboolean isSafeChar(int c) { if (c >= 'a' && c <= 'z') { returntrue;
} if (c >= 'A' && c <= 'Z') { returntrue;
} if (c >= '0' && c <= '9') { returntrue;
} if (c == '-' || c == '_' || c == '.' || c == '!' ||
c == '~' || c == '*' || c == '\'' || c == '(' || c == ')') { returntrue;
} returnfalse;
}
publicstaticvoid releaseTag(Tag tag, InstanceManager instanceManager, boolean reused) { // Caller ensures pool is non-null if reuse is true if (!reused) {
releaseTag(tag, instanceManager);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.