0001: /*
0002: * Copyright 1999,2004 The Apache Software Foundation.
0003: *
0004: * Licensed under the Apache License, Version 2.0 (the "License");
0005: * you may not use this file except in compliance with the License.
0006: * You may obtain a copy of the License at
0007: *
0008: * http://www.apache.org/licenses/LICENSE-2.0
0009: *
0010: * Unless required by applicable law or agreed to in writing, software
0011: * distributed under the License is distributed on an "AS IS" BASIS,
0012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013: * See the License for the specific language governing permissions and
0014: * limitations under the License.
0015: */
0016:
0017: package org.apache.jasper.runtime;
0018:
0019: import java.beans.PropertyEditor;
0020: import java.beans.PropertyEditorManager;
0021: import java.io.ByteArrayOutputStream;
0022: import java.io.IOException;
0023: import java.io.OutputStreamWriter;
0024: import java.lang.reflect.Method;
0025: import java.security.AccessController;
0026: import java.security.PrivilegedActionException;
0027: import java.security.PrivilegedExceptionAction;
0028: import java.util.Enumeration;
0029:
0030: import javax.servlet.RequestDispatcher;
0031: import javax.servlet.ServletException;
0032: import javax.servlet.ServletRequest;
0033: import javax.servlet.ServletResponse;
0034: import javax.servlet.http.HttpServletRequest;
0035: import javax.servlet.jsp.JspWriter;
0036: import javax.servlet.jsp.PageContext;
0037: import javax.servlet.jsp.tagext.BodyContent;
0038:
0039: import org.apache.jasper.JasperException;
0040: import org.apache.jasper.compiler.Localizer;
0041:
0042: /**
0043: * Bunch of util methods that are used by code generated for useBean,
0044: * getProperty and setProperty.
0045: *
0046: * The __begin, __end stuff is there so that the JSP engine can
0047: * actually parse this file and inline them if people don't want
0048: * runtime dependencies on this class. However, I'm not sure if that
0049: * works so well right now. It got forgotten at some point. -akv
0050: *
0051: * @author Mandar Raje
0052: * @author Shawn Bayern
0053: */
0054: public class JspRuntimeLibrary {
0055:
0056: private static final String SERVLET_EXCEPTION = "javax.servlet.error.exception";
0057: private static final String JSP_EXCEPTION = "javax.servlet.jsp.jspException";
0058:
0059: protected static class PrivilegedIntrospectHelper implements
0060: PrivilegedExceptionAction {
0061:
0062: private Object bean;
0063: private String prop;
0064: private String value;
0065: private ServletRequest request;
0066: private String param;
0067: private boolean ignoreMethodNF;
0068:
0069: PrivilegedIntrospectHelper(Object bean, String prop,
0070: String value, ServletRequest request, String param,
0071: boolean ignoreMethodNF) {
0072: this .bean = bean;
0073: this .prop = prop;
0074: this .value = value;
0075: this .request = request;
0076: this .param = param;
0077: this .ignoreMethodNF = ignoreMethodNF;
0078: }
0079:
0080: public Object run() throws JasperException {
0081: internalIntrospecthelper(bean, prop, value, request, param,
0082: ignoreMethodNF);
0083: return null;
0084: }
0085: }
0086:
0087: /**
0088: * Returns the value of the javax.servlet.error.exception request
0089: * attribute value, if present, otherwise the value of the
0090: * javax.servlet.jsp.jspException request attribute value.
0091: *
0092: * This method is called at the beginning of the generated servlet code
0093: * for a JSP error page, when the "exception" implicit scripting language
0094: * variable is initialized.
0095: */
0096: public static Throwable getThrowable(ServletRequest request) {
0097: Throwable error = (Throwable) request
0098: .getAttribute(SERVLET_EXCEPTION);
0099: if (error == null) {
0100: error = (Throwable) request.getAttribute(JSP_EXCEPTION);
0101: if (error != null) {
0102: /*
0103: * The only place that sets JSP_EXCEPTION is
0104: * PageContextImpl.handlePageException(). It really should set
0105: * SERVLET_EXCEPTION, but that would interfere with the
0106: * ErrorReportValve. Therefore, if JSP_EXCEPTION is set, we
0107: * need to set SERVLET_EXCEPTION.
0108: */
0109: request.setAttribute(SERVLET_EXCEPTION, error);
0110: }
0111: }
0112:
0113: return error;
0114: }
0115:
0116: public static boolean coerceToBoolean(String s) {
0117: if (s == null || s.length() == 0)
0118: return false;
0119: else
0120: return Boolean.valueOf(s).booleanValue();
0121: }
0122:
0123: public static byte coerceToByte(String s) {
0124: if (s == null || s.length() == 0)
0125: return (byte) 0;
0126: else
0127: return Byte.valueOf(s).byteValue();
0128: }
0129:
0130: public static char coerceToChar(String s) {
0131: if (s == null || s.length() == 0) {
0132: return (char) 0;
0133: } else {
0134: // this trick avoids escaping issues
0135: return (char) (int) s.charAt(0);
0136: }
0137: }
0138:
0139: public static double coerceToDouble(String s) {
0140: if (s == null || s.length() == 0)
0141: return (double) 0;
0142: else
0143: return Double.valueOf(s).doubleValue();
0144: }
0145:
0146: public static float coerceToFloat(String s) {
0147: if (s == null || s.length() == 0)
0148: return (float) 0;
0149: else
0150: return Float.valueOf(s).floatValue();
0151: }
0152:
0153: public static int coerceToInt(String s) {
0154: if (s == null || s.length() == 0)
0155: return 0;
0156: else
0157: return Integer.valueOf(s).intValue();
0158: }
0159:
0160: public static short coerceToShort(String s) {
0161: if (s == null || s.length() == 0)
0162: return (short) 0;
0163: else
0164: return Short.valueOf(s).shortValue();
0165: }
0166:
0167: public static long coerceToLong(String s) {
0168: if (s == null || s.length() == 0)
0169: return (long) 0;
0170: else
0171: return Long.valueOf(s).longValue();
0172: }
0173:
0174: public static Object coerce(String s, Class target) {
0175:
0176: boolean isNullOrEmpty = (s == null || s.length() == 0);
0177:
0178: if (target == Boolean.class) {
0179: if (isNullOrEmpty) {
0180: s = "false";
0181: }
0182: return new Boolean(s);
0183: } else if (target == Byte.class) {
0184: if (isNullOrEmpty)
0185: return new Byte((byte) 0);
0186: else
0187: return new Byte(s);
0188: } else if (target == Character.class) {
0189: if (isNullOrEmpty)
0190: return new Character((char) 0);
0191: else
0192: return new Character(s.charAt(0));
0193: } else if (target == Double.class) {
0194: if (isNullOrEmpty)
0195: return new Double(0);
0196: else
0197: return new Double(s);
0198: } else if (target == Float.class) {
0199: if (isNullOrEmpty)
0200: return new Float(0);
0201: else
0202: return new Float(s);
0203: } else if (target == Integer.class) {
0204: if (isNullOrEmpty)
0205: return new Integer(0);
0206: else
0207: return new Integer(s);
0208: } else if (target == Short.class) {
0209: if (isNullOrEmpty)
0210: return new Short((short) 0);
0211: else
0212: return new Short(s);
0213: } else if (target == Long.class) {
0214: if (isNullOrEmpty)
0215: return new Long(0);
0216: else
0217: return new Long(s);
0218: } else {
0219: return null;
0220: }
0221: }
0222:
0223: // __begin convertMethod
0224: public static Object convert(String propertyName, String s,
0225: Class t, Class propertyEditorClass) throws JasperException {
0226: try {
0227: if (s == null) {
0228: if (t.equals(Boolean.class) || t.equals(Boolean.TYPE))
0229: s = "false";
0230: else
0231: return null;
0232: }
0233: if (propertyEditorClass != null) {
0234: return getValueFromBeanInfoPropertyEditor(t,
0235: propertyName, s, propertyEditorClass);
0236: } else if (t.equals(Boolean.class)
0237: || t.equals(Boolean.TYPE)) {
0238: if (s.equalsIgnoreCase("on")
0239: || s.equalsIgnoreCase("true"))
0240: s = "true";
0241: else
0242: s = "false";
0243: return new Boolean(s);
0244: } else if (t.equals(Byte.class) || t.equals(Byte.TYPE)) {
0245: return new Byte(s);
0246: } else if (t.equals(Character.class)
0247: || t.equals(Character.TYPE)) {
0248: return s.length() > 0 ? new Character(s.charAt(0))
0249: : null;
0250: } else if (t.equals(Short.class) || t.equals(Short.TYPE)) {
0251: return new Short(s);
0252: } else if (t.equals(Integer.class)
0253: || t.equals(Integer.TYPE)) {
0254: return new Integer(s);
0255: } else if (t.equals(Float.class) || t.equals(Float.TYPE)) {
0256: return new Float(s);
0257: } else if (t.equals(Long.class) || t.equals(Long.TYPE)) {
0258: return new Long(s);
0259: } else if (t.equals(Double.class) || t.equals(Double.TYPE)) {
0260: return new Double(s);
0261: } else if (t.equals(String.class)) {
0262: return s;
0263: } else if (t.equals(java.io.File.class)) {
0264: return new java.io.File(s);
0265: } else if (t.getName().equals("java.lang.Object")) {
0266: return new Object[] { s };
0267: } else {
0268: return getValueFromPropertyEditorManager(t,
0269: propertyName, s);
0270: }
0271: } catch (Exception ex) {
0272: throw new JasperException(ex);
0273: }
0274: }
0275:
0276: // __end convertMethod
0277:
0278: // __begin introspectMethod
0279: public static void introspect(Object bean, ServletRequest request)
0280: throws JasperException {
0281: Enumeration e = request.getParameterNames();
0282: while (e.hasMoreElements()) {
0283: String name = (String) e.nextElement();
0284: String value = request.getParameter(name);
0285: introspecthelper(bean, name, value, request, name, true);
0286: }
0287: }
0288:
0289: // __end introspectMethod
0290:
0291: // __begin introspecthelperMethod
0292: public static void introspecthelper(Object bean, String prop,
0293: String value, ServletRequest request, String param,
0294: boolean ignoreMethodNF) throws JasperException {
0295: if (System.getSecurityManager() != null) {
0296: try {
0297: PrivilegedIntrospectHelper dp = new PrivilegedIntrospectHelper(
0298: bean, prop, value, request, param,
0299: ignoreMethodNF);
0300: AccessController.doPrivileged(dp);
0301: } catch (PrivilegedActionException pe) {
0302: Exception e = pe.getException();
0303: throw (JasperException) e;
0304: }
0305: } else {
0306: internalIntrospecthelper(bean, prop, value, request, param,
0307: ignoreMethodNF);
0308: }
0309: }
0310:
0311: private static void internalIntrospecthelper(Object bean,
0312: String prop, String value, ServletRequest request,
0313: String param, boolean ignoreMethodNF)
0314: throws JasperException {
0315: Method method = null;
0316: Class type = null;
0317: Class propertyEditorClass = null;
0318: try {
0319: java.beans.BeanInfo info = java.beans.Introspector
0320: .getBeanInfo(bean.getClass());
0321: if (info != null) {
0322: java.beans.PropertyDescriptor pd[] = info
0323: .getPropertyDescriptors();
0324: for (int i = 0; i < pd.length; i++) {
0325: if (pd[i].getName().equals(prop)) {
0326: method = pd[i].getWriteMethod();
0327: type = pd[i].getPropertyType();
0328: propertyEditorClass = pd[i]
0329: .getPropertyEditorClass();
0330: break;
0331: }
0332: }
0333: }
0334: if (method != null) {
0335: if (type.isArray()) {
0336: if (request == null) {
0337: throw new JasperException(
0338: Localizer
0339: .getMessage("jsp.error.beans.setproperty.noindexset"));
0340: }
0341: Class t = type.getComponentType();
0342: String[] values = request.getParameterValues(param);
0343: //XXX Please check.
0344: if (values == null)
0345: return;
0346: if (t.equals(String.class)) {
0347: method.invoke(bean, new Object[] { values });
0348: } else {
0349: Object tmpval = null;
0350: createTypedArray(prop, bean, method, values, t,
0351: propertyEditorClass);
0352: }
0353: } else {
0354: if (value == null
0355: || (param != null && value.equals("")))
0356: return;
0357: Object oval = convert(prop, value, type,
0358: propertyEditorClass);
0359: if (oval != null)
0360: method.invoke(bean, new Object[] { oval });
0361: }
0362: }
0363: } catch (Exception ex) {
0364: throw new JasperException(ex);
0365: }
0366: if (!ignoreMethodNF && (method == null)) {
0367: if (type == null) {
0368: throw new JasperException(Localizer.getMessage(
0369: "jsp.error.beans.noproperty", prop, bean
0370: .getClass().getName()));
0371: } else {
0372: throw new JasperException(Localizer.getMessage(
0373: "jsp.error.beans.nomethod.setproperty", prop,
0374: type.getName(), bean.getClass().getName()));
0375: }
0376: }
0377: }
0378:
0379: // __end introspecthelperMethod
0380:
0381: //-------------------------------------------------------------------
0382: // functions to convert builtin Java data types to string.
0383: //-------------------------------------------------------------------
0384: // __begin toStringMethod
0385: public static String toString(Object o) {
0386: return String.valueOf(o);
0387: }
0388:
0389: public static String toString(byte b) {
0390: return new Byte(b).toString();
0391: }
0392:
0393: public static String toString(boolean b) {
0394: return new Boolean(b).toString();
0395: }
0396:
0397: public static String toString(short s) {
0398: return new Short(s).toString();
0399: }
0400:
0401: public static String toString(int i) {
0402: return new Integer(i).toString();
0403: }
0404:
0405: public static String toString(float f) {
0406: return new Float(f).toString();
0407: }
0408:
0409: public static String toString(long l) {
0410: return new Long(l).toString();
0411: }
0412:
0413: public static String toString(double d) {
0414: return new Double(d).toString();
0415: }
0416:
0417: public static String toString(char c) {
0418: return new Character(c).toString();
0419: }
0420:
0421: // __end toStringMethod
0422:
0423: /**
0424: * Create a typed array.
0425: * This is a special case where params are passed through
0426: * the request and the property is indexed.
0427: */
0428: public static void createTypedArray(String propertyName,
0429: Object bean, Method method, String[] values, Class t,
0430: Class propertyEditorClass) throws JasperException {
0431:
0432: try {
0433: if (propertyEditorClass != null) {
0434: Object[] tmpval = new Integer[values.length];
0435: for (int i = 0; i < values.length; i++) {
0436: tmpval[i] = getValueFromBeanInfoPropertyEditor(t,
0437: propertyName, values[i],
0438: propertyEditorClass);
0439: }
0440: method.invoke(bean, new Object[] { tmpval });
0441: } else if (t.equals(Integer.class)) {
0442: Integer[] tmpval = new Integer[values.length];
0443: for (int i = 0; i < values.length; i++)
0444: tmpval[i] = new Integer(values[i]);
0445: method.invoke(bean, new Object[] { tmpval });
0446: } else if (t.equals(Byte.class)) {
0447: Byte[] tmpval = new Byte[values.length];
0448: for (int i = 0; i < values.length; i++)
0449: tmpval[i] = new Byte(values[i]);
0450: method.invoke(bean, new Object[] { tmpval });
0451: } else if (t.equals(Boolean.class)) {
0452: Boolean[] tmpval = new Boolean[values.length];
0453: for (int i = 0; i < values.length; i++)
0454: tmpval[i] = new Boolean(values[i]);
0455: method.invoke(bean, new Object[] { tmpval });
0456: } else if (t.equals(Short.class)) {
0457: Short[] tmpval = new Short[values.length];
0458: for (int i = 0; i < values.length; i++)
0459: tmpval[i] = new Short(values[i]);
0460: method.invoke(bean, new Object[] { tmpval });
0461: } else if (t.equals(Long.class)) {
0462: Long[] tmpval = new Long[values.length];
0463: for (int i = 0; i < values.length; i++)
0464: tmpval[i] = new Long(values[i]);
0465: method.invoke(bean, new Object[] { tmpval });
0466: } else if (t.equals(Double.class)) {
0467: Double[] tmpval = new Double[values.length];
0468: for (int i = 0; i < values.length; i++)
0469: tmpval[i] = new Double(values[i]);
0470: method.invoke(bean, new Object[] { tmpval });
0471: } else if (t.equals(Float.class)) {
0472: Float[] tmpval = new Float[values.length];
0473: for (int i = 0; i < values.length; i++)
0474: tmpval[i] = new Float(values[i]);
0475: method.invoke(bean, new Object[] { tmpval });
0476: } else if (t.equals(Character.class)) {
0477: Character[] tmpval = new Character[values.length];
0478: for (int i = 0; i < values.length; i++)
0479: tmpval[i] = new Character(values[i].charAt(0));
0480: method.invoke(bean, new Object[] { tmpval });
0481: } else if (t.equals(int.class)) {
0482: int[] tmpval = new int[values.length];
0483: for (int i = 0; i < values.length; i++)
0484: tmpval[i] = Integer.parseInt(values[i]);
0485: method.invoke(bean, new Object[] { tmpval });
0486: } else if (t.equals(byte.class)) {
0487: byte[] tmpval = new byte[values.length];
0488: for (int i = 0; i < values.length; i++)
0489: tmpval[i] = Byte.parseByte(values[i]);
0490: method.invoke(bean, new Object[] { tmpval });
0491: } else if (t.equals(boolean.class)) {
0492: boolean[] tmpval = new boolean[values.length];
0493: for (int i = 0; i < values.length; i++)
0494: tmpval[i] = (Boolean.valueOf(values[i]))
0495: .booleanValue();
0496: method.invoke(bean, new Object[] { tmpval });
0497: } else if (t.equals(short.class)) {
0498: short[] tmpval = new short[values.length];
0499: for (int i = 0; i < values.length; i++)
0500: tmpval[i] = Short.parseShort(values[i]);
0501: method.invoke(bean, new Object[] { tmpval });
0502: } else if (t.equals(long.class)) {
0503: long[] tmpval = new long[values.length];
0504: for (int i = 0; i < values.length; i++)
0505: tmpval[i] = Long.parseLong(values[i]);
0506: method.invoke(bean, new Object[] { tmpval });
0507: } else if (t.equals(double.class)) {
0508: double[] tmpval = new double[values.length];
0509: for (int i = 0; i < values.length; i++)
0510: tmpval[i] = Double.valueOf(values[i]).doubleValue();
0511: method.invoke(bean, new Object[] { tmpval });
0512: } else if (t.equals(float.class)) {
0513: float[] tmpval = new float[values.length];
0514: for (int i = 0; i < values.length; i++)
0515: tmpval[i] = Float.valueOf(values[i]).floatValue();
0516: method.invoke(bean, new Object[] { tmpval });
0517: } else if (t.equals(char.class)) {
0518: char[] tmpval = new char[values.length];
0519: for (int i = 0; i < values.length; i++)
0520: tmpval[i] = values[i].charAt(0);
0521: method.invoke(bean, new Object[] { tmpval });
0522: } else {
0523: Object[] tmpval = new Integer[values.length];
0524: for (int i = 0; i < values.length; i++) {
0525: tmpval[i] = getValueFromPropertyEditorManager(t,
0526: propertyName, values[i]);
0527: }
0528: method.invoke(bean, new Object[] { tmpval });
0529: }
0530: } catch (Exception ex) {
0531: throw new JasperException("error in invoking method", ex);
0532: }
0533: }
0534:
0535: /**
0536: * Escape special shell characters.
0537: * @param unescString The string to shell-escape
0538: * @return The escaped shell string.
0539: */
0540:
0541: public static String escapeQueryString(String unescString) {
0542: if (unescString == null)
0543: return null;
0544:
0545: String escString = "";
0546: String shellSpChars = "&;`'\"|*?~<>^()[]{}$\\\n";
0547:
0548: for (int index = 0; index < unescString.length(); index++) {
0549: char nextChar = unescString.charAt(index);
0550:
0551: if (shellSpChars.indexOf(nextChar) != -1)
0552: escString += "\\";
0553:
0554: escString += nextChar;
0555: }
0556: return escString;
0557: }
0558:
0559: /**
0560: * Decode an URL formatted string.
0561: * @param encoded The string to decode.
0562: * @return The decoded string.
0563: */
0564:
0565: public static String decode(String encoded) {
0566: // speedily leave if we're not needed
0567: if (encoded == null)
0568: return null;
0569: if (encoded.indexOf('%') == -1 && encoded.indexOf('+') == -1)
0570: return encoded;
0571:
0572: //allocate the buffer - use byte[] to avoid calls to new.
0573: byte holdbuffer[] = new byte[encoded.length()];
0574:
0575: char holdchar;
0576: int bufcount = 0;
0577:
0578: for (int count = 0; count < encoded.length(); count++) {
0579: char cur = encoded.charAt(count);
0580: if (cur == '%') {
0581: holdbuffer[bufcount++] = (byte) Integer.parseInt(
0582: encoded.substring(count + 1, count + 3), 16);
0583: if (count + 2 >= encoded.length())
0584: count = encoded.length();
0585: else
0586: count += 2;
0587: } else if (cur == '+') {
0588: holdbuffer[bufcount++] = (byte) ' ';
0589: } else {
0590: holdbuffer[bufcount++] = (byte) cur;
0591: }
0592: }
0593: // REVISIT -- remedy for Deprecated warning.
0594: //return new String(holdbuffer,0,0,bufcount);
0595: return new String(holdbuffer, 0, bufcount);
0596: }
0597:
0598: // __begin lookupReadMethodMethod
0599: public static Object handleGetProperty(Object o, String prop)
0600: throws JasperException {
0601: if (o == null) {
0602: throw new JasperException(Localizer
0603: .getMessage("jsp.error.beans.nullbean"));
0604: }
0605: Object value = null;
0606: try {
0607: Method method = getReadMethod(o.getClass(), prop);
0608: value = method.invoke(o, null);
0609: } catch (Exception ex) {
0610: throw new JasperException(ex);
0611: }
0612: return value;
0613: }
0614:
0615: // __end lookupReadMethodMethod
0616:
0617: // handles <jsp:setProperty> with EL expression for 'value' attribute
0618: /** Use proprietaryEvaluate
0619: public static void handleSetPropertyExpression(Object bean,
0620: String prop, String expression, PageContext pageContext,
0621: VariableResolver variableResolver, FunctionMapper functionMapper )
0622: throws JasperException
0623: {
0624: try {
0625: Method method = getWriteMethod(bean.getClass(), prop);
0626: method.invoke(bean, new Object[] {
0627: pageContext.getExpressionEvaluator().evaluate(
0628: expression,
0629: method.getParameterTypes()[0],
0630: variableResolver,
0631: functionMapper,
0632: null )
0633: });
0634: } catch (Exception ex) {
0635: throw new JasperException(ex);
0636: }
0637: }
0638: **/
0639: public static void handleSetPropertyExpression(Object bean,
0640: String prop, String expression, PageContext pageContext,
0641: ProtectedFunctionMapper functionMapper)
0642: throws JasperException {
0643: try {
0644: Method method = getWriteMethod(bean.getClass(), prop);
0645: method.invoke(bean, new Object[] { PageContextImpl
0646: .proprietaryEvaluate(expression, method
0647: .getParameterTypes()[0], pageContext,
0648: functionMapper, false) });
0649: } catch (Exception ex) {
0650: throw new JasperException(ex);
0651: }
0652: }
0653:
0654: public static void handleSetProperty(Object bean, String prop,
0655: Object value) throws JasperException {
0656: try {
0657: Method method = getWriteMethod(bean.getClass(), prop);
0658: method.invoke(bean, new Object[] { value });
0659: } catch (Exception ex) {
0660: throw new JasperException(ex);
0661: }
0662: }
0663:
0664: public static void handleSetProperty(Object bean, String prop,
0665: int value) throws JasperException {
0666: try {
0667: Method method = getWriteMethod(bean.getClass(), prop);
0668: method.invoke(bean, new Object[] { new Integer(value) });
0669: } catch (Exception ex) {
0670: throw new JasperException(ex);
0671: }
0672: }
0673:
0674: public static void handleSetProperty(Object bean, String prop,
0675: short value) throws JasperException {
0676: try {
0677: Method method = getWriteMethod(bean.getClass(), prop);
0678: method.invoke(bean, new Object[] { new Short(value) });
0679: } catch (Exception ex) {
0680: throw new JasperException(ex);
0681: }
0682: }
0683:
0684: public static void handleSetProperty(Object bean, String prop,
0685: long value) throws JasperException {
0686: try {
0687: Method method = getWriteMethod(bean.getClass(), prop);
0688: method.invoke(bean, new Object[] { new Long(value) });
0689: } catch (Exception ex) {
0690: throw new JasperException(ex);
0691: }
0692: }
0693:
0694: public static void handleSetProperty(Object bean, String prop,
0695: double value) throws JasperException {
0696: try {
0697: Method method = getWriteMethod(bean.getClass(), prop);
0698: method.invoke(bean, new Object[] { new Double(value) });
0699: } catch (Exception ex) {
0700: throw new JasperException(ex);
0701: }
0702: }
0703:
0704: public static void handleSetProperty(Object bean, String prop,
0705: float value) throws JasperException {
0706: try {
0707: Method method = getWriteMethod(bean.getClass(), prop);
0708: method.invoke(bean, new Object[] { new Float(value) });
0709: } catch (Exception ex) {
0710: throw new JasperException(ex);
0711: }
0712: }
0713:
0714: public static void handleSetProperty(Object bean, String prop,
0715: char value) throws JasperException {
0716: try {
0717: Method method = getWriteMethod(bean.getClass(), prop);
0718: method.invoke(bean, new Object[] { new Character(value) });
0719: } catch (Exception ex) {
0720: throw new JasperException(ex);
0721: }
0722: }
0723:
0724: public static void handleSetProperty(Object bean, String prop,
0725: byte value) throws JasperException {
0726: try {
0727: Method method = getWriteMethod(bean.getClass(), prop);
0728: method.invoke(bean, new Object[] { new Byte(value) });
0729: } catch (Exception ex) {
0730: throw new JasperException(ex);
0731: }
0732: }
0733:
0734: public static void handleSetProperty(Object bean, String prop,
0735: boolean value) throws JasperException {
0736: try {
0737: Method method = getWriteMethod(bean.getClass(), prop);
0738: method.invoke(bean, new Object[] { new Boolean(value) });
0739: } catch (Exception ex) {
0740: throw new JasperException(ex);
0741: }
0742: }
0743:
0744: public static Method getWriteMethod(Class beanClass, String prop)
0745: throws JasperException {
0746: Method method = null;
0747: Class type = null;
0748: try {
0749: java.beans.BeanInfo info = java.beans.Introspector
0750: .getBeanInfo(beanClass);
0751: if (info != null) {
0752: java.beans.PropertyDescriptor pd[] = info
0753: .getPropertyDescriptors();
0754: for (int i = 0; i < pd.length; i++) {
0755: if (pd[i].getName().equals(prop)) {
0756: method = pd[i].getWriteMethod();
0757: type = pd[i].getPropertyType();
0758: break;
0759: }
0760: }
0761: } else {
0762: // just in case introspection silently fails.
0763: throw new JasperException(Localizer.getMessage(
0764: "jsp.error.beans.nobeaninfo", beanClass
0765: .getName()));
0766: }
0767: } catch (Exception ex) {
0768: throw new JasperException(ex);
0769: }
0770: if (method == null) {
0771: if (type == null) {
0772: throw new JasperException(Localizer.getMessage(
0773: "jsp.error.beans.noproperty", prop, beanClass
0774: .getName()));
0775: } else {
0776: throw new JasperException(Localizer.getMessage(
0777: "jsp.error.beans.nomethod.setproperty", prop,
0778: type.getName(), beanClass.getName()));
0779: }
0780: }
0781: return method;
0782: }
0783:
0784: public static Method getReadMethod(Class beanClass, String prop)
0785: throws JasperException {
0786:
0787: Method method = null;
0788: Class type = null;
0789: try {
0790: java.beans.BeanInfo info = java.beans.Introspector
0791: .getBeanInfo(beanClass);
0792: if (info != null) {
0793: java.beans.PropertyDescriptor pd[] = info
0794: .getPropertyDescriptors();
0795: for (int i = 0; i < pd.length; i++) {
0796: if (pd[i].getName().equals(prop)) {
0797: method = pd[i].getReadMethod();
0798: type = pd[i].getPropertyType();
0799: break;
0800: }
0801: }
0802: } else {
0803: // just in case introspection silently fails.
0804: throw new JasperException(Localizer.getMessage(
0805: "jsp.error.beans.nobeaninfo", beanClass
0806: .getName()));
0807: }
0808: } catch (Exception ex) {
0809: throw new JasperException(ex);
0810: }
0811: if (method == null) {
0812: if (type == null) {
0813: throw new JasperException(Localizer.getMessage(
0814: "jsp.error.beans.noproperty", prop, beanClass
0815: .getName()));
0816: } else {
0817: throw new JasperException(Localizer.getMessage(
0818: "jsp.error.beans.nomethod", prop, beanClass
0819: .getName()));
0820: }
0821: }
0822:
0823: return method;
0824: }
0825:
0826: //*********************************************************************
0827: // PropertyEditor Support
0828:
0829: public static Object getValueFromBeanInfoPropertyEditor(
0830: Class attrClass, String attrName, String attrValue,
0831: Class propertyEditorClass) throws JasperException {
0832: try {
0833: PropertyEditor pe = (PropertyEditor) propertyEditorClass
0834: .newInstance();
0835: pe.setAsText(attrValue);
0836: return pe.getValue();
0837: } catch (Exception ex) {
0838: throw new JasperException(Localizer.getMessage(
0839: "jsp.error.beans.property.conversion", attrValue,
0840: attrClass.getName(), attrName, ex.getMessage()));
0841: }
0842: }
0843:
0844: public static Object getValueFromPropertyEditorManager(
0845: Class attrClass, String attrName, String attrValue)
0846: throws JasperException {
0847: try {
0848: PropertyEditor propEditor = PropertyEditorManager
0849: .findEditor(attrClass);
0850: if (propEditor != null) {
0851: propEditor.setAsText(attrValue);
0852: return propEditor.getValue();
0853: } else {
0854: throw new IllegalArgumentException(
0855: Localizer
0856: .getMessage("jsp.error.beans.propertyeditor.notregistered"));
0857: }
0858: } catch (IllegalArgumentException ex) {
0859: throw new JasperException(Localizer.getMessage(
0860: "jsp.error.beans.property.conversion", attrValue,
0861: attrClass.getName(), attrName, ex.getMessage()));
0862: }
0863: }
0864:
0865: // ************************************************************************
0866: // General Purpose Runtime Methods
0867: // ************************************************************************
0868:
0869: /**
0870: * Convert a possibly relative resource path into a context-relative
0871: * resource path that starts with a '/'.
0872: *
0873: * @param request The servlet request we are processing
0874: * @param relativePath The possibly relative resource path
0875: */
0876: public static String getContextRelativePath(ServletRequest request,
0877: String relativePath) {
0878:
0879: if (relativePath.startsWith("/"))
0880: return (relativePath);
0881: if (!(request instanceof HttpServletRequest))
0882: return (relativePath);
0883: HttpServletRequest hrequest = (HttpServletRequest) request;
0884: String uri = (String) request
0885: .getAttribute("javax.servlet.include.servlet_path");
0886: if (uri != null) {
0887: String pathInfo = (String) request
0888: .getAttribute("javax.servlet.include.path_info");
0889: if (pathInfo == null) {
0890: if (uri.lastIndexOf('/') >= 0)
0891: uri = uri.substring(0, uri.lastIndexOf('/'));
0892: }
0893: } else {
0894: uri = hrequest.getServletPath();
0895: if (uri.lastIndexOf('/') >= 0)
0896: uri = uri.substring(0, uri.lastIndexOf('/'));
0897: }
0898: return uri + '/' + relativePath;
0899:
0900: }
0901:
0902: /**
0903: * Perform a RequestDispatcher.include() operation, with optional flushing
0904: * of the response beforehand.
0905: *
0906: * @param request The servlet request we are processing
0907: * @param response The servlet response we are processing
0908: * @param relativePath The relative path of the resource to be included
0909: * @param out The Writer to whom we are currently writing
0910: * @param flush Should we flush before the include is processed?
0911: *
0912: * @exception IOException if thrown by the included servlet
0913: * @exception ServletException if thrown by the included servlet
0914: */
0915: public static void include(ServletRequest request,
0916: ServletResponse response, String relativePath,
0917: JspWriter out, boolean flush) throws IOException,
0918: ServletException {
0919:
0920: if (flush && !(out instanceof BodyContent))
0921: out.flush();
0922:
0923: // FIXME - It is tempting to use request.getRequestDispatcher() to
0924: // resolve a relative path directly, but Catalina currently does not
0925: // take into account whether the caller is inside a RequestDispatcher
0926: // include or not. Whether Catalina *should* take that into account
0927: // is a spec issue currently under review. In the mean time,
0928: // replicate Jasper's previous behavior
0929:
0930: String resourcePath = getContextRelativePath(request,
0931: relativePath);
0932: RequestDispatcher rd = request
0933: .getRequestDispatcher(resourcePath);
0934:
0935: rd.include(request, new ServletResponseWrapperInclude(response,
0936: out));
0937:
0938: }
0939:
0940: /**
0941: * URL encodes a string, based on the supplied character encoding.
0942: * This performs the same function as java.next.URLEncode.encode
0943: * in J2SDK1.4, and should be removed if the only platform supported
0944: * is 1.4 or higher.
0945: * @param s The String to be URL encoded.
0946: * @param enc The character encoding
0947: * @return The URL encoded String
0948: */
0949: public static String URLEncode(String s, String enc) {
0950:
0951: if (s == null) {
0952: return "null";
0953: }
0954:
0955: if (enc == null) {
0956: enc = "ISO-8859-1"; // The default request encoding
0957: }
0958:
0959: StringBuffer out = new StringBuffer(s.length());
0960: ByteArrayOutputStream buf = new ByteArrayOutputStream();
0961: OutputStreamWriter writer = null;
0962: try {
0963: writer = new OutputStreamWriter(buf, enc);
0964: } catch (java.io.UnsupportedEncodingException ex) {
0965: // Use the default encoding?
0966: writer = new OutputStreamWriter(buf);
0967: }
0968:
0969: for (int i = 0; i < s.length(); i++) {
0970: int c = s.charAt(i);
0971: if (c == ' ') {
0972: out.append('+');
0973: } else if (isSafeChar(c)) {
0974: out.append((char) c);
0975: } else {
0976: // convert to external encoding before hex conversion
0977: try {
0978: writer.write(c);
0979: writer.flush();
0980: } catch (IOException e) {
0981: buf.reset();
0982: continue;
0983: }
0984: byte[] ba = buf.toByteArray();
0985: for (int j = 0; j < ba.length; j++) {
0986: out.append('%');
0987: // Converting each byte in the buffer
0988: out.append(Character.forDigit((ba[j] >> 4) & 0xf,
0989: 16));
0990: out.append(Character.forDigit(ba[j] & 0xf, 16));
0991: }
0992: buf.reset();
0993: }
0994: }
0995: return out.toString();
0996: }
0997:
0998: private static boolean isSafeChar(int c) {
0999: if (c >= 'a' && c <= 'z') {
1000: return true;
1001: }
1002: if (c >= 'A' && c <= 'Z') {
1003: return true;
1004: }
1005: if (c >= '0' && c <= '9') {
1006: return true;
1007: }
1008: if (c == '-' || c == '_' || c == '.' || c == '!' || c == '~'
1009: || c == '*' || c == '\'' || c == '(' || c == ')') {
1010: return true;
1011: }
1012: return false;
1013: }
1014:
1015: }
|