001: /*
002: * The Apache Software License, Version 1.1
003: *
004: * Copyright (c) 1999 The Apache Software Foundation. All rights
005: * reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: *
014: * 2. Redistributions in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * 3. The end-user documentation included with the redistribution, if
020: * any, must include the following acknowlegement:
021: * "This product includes software developed by the
022: * Apache Software Foundation (http://www.apache.org/)."
023: * Alternately, this acknowlegement may appear in the software itself,
024: * if and wherever such third-party acknowlegements normally appear.
025: *
026: * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
027: * Foundation" must not be used to endorse or promote products derived
028: * from this software without prior written permission. For written
029: * permission, please contact apache@apache.org.
030: *
031: * 5. Products derived from this software may not be called "Apache"
032: * nor may "Apache" appear in their names without prior written
033: * permission of the Apache Group.
034: *
035: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
039: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
040: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
041: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
042: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
043: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
044: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
045: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
046: * SUCH DAMAGE.
047: * ====================================================================
048: *
049: * This software consists of voluntary contributions made by many
050: * individuals on behalf of the Apache Software Foundation. For more
051: * information on the Apache Software Foundation, please see
052: * <http://www.apache.org/>.
053: *
054: */
055:
056: package com.sun.portal.providers.jsp.jasper3.jasper.runtime;
057:
058: import java.io.IOException;
059: import java.util.Enumeration;
060:
061: import java.lang.reflect.Method;
062:
063: import java.io.Writer;
064: import java.io.Reader;
065: import java.io.IOException;
066: import java.io.InputStreamReader;
067:
068: import java.beans.PropertyDescriptor;
069: import java.beans.IndexedPropertyDescriptor;
070:
071: import javax.servlet.ServletException;
072: import javax.servlet.ServletRequest;
073: import javax.servlet.ServletContext;
074: import javax.servlet.http.HttpServletRequest;
075: import javax.servlet.http.HttpSession;
076:
077: import com.sun.portal.providers.jsp.jasper3.jasper.JasperException;
078: import com.sun.portal.providers.jsp.jasper3.jasper.Constants;
079:
080: /**
081: * Bunch of util methods that are used by code generated for useBean,
082: * getProperty and setProperty.
083: *
084: * The __begin, __end stuff is there so that the JSP engine can
085: * actually parse this file and inline them if people don't want
086: * runtime dependencies on this class. However, I'm not sure if that
087: * works so well right now. It got forgotten at some point. -akv
088: *
089: * @author Mandar Raje
090: */
091: public class JspRuntimeLibrary {
092:
093: // __begin convertMethod
094: public static Object convert(String s, Class t)
095: throws JasperException {
096: try {
097: if (s == null) {
098: if (t.equals(Boolean.class) || t.equals(Boolean.TYPE))
099: s = "false";
100: else
101: return null;
102: }
103:
104: if (t.equals(Boolean.class) || t.equals(Boolean.TYPE)) {
105: if (s.equalsIgnoreCase("on")
106: || s.equalsIgnoreCase("true"))
107: s = "true";
108: else
109: s = "false";
110: return new Boolean(s);
111: } else if (t.equals(Byte.class) || t.equals(Byte.TYPE)) {
112: return new Byte(s);
113: } else if (t.equals(Character.class)
114: || t.equals(Character.TYPE)) {
115: return s.length() > 0 ? new Character(s.charAt(0))
116: : null;
117: } else if (t.equals(Short.class) || t.equals(Short.TYPE)) {
118: return new Short(s);
119: } else if (t.equals(Integer.class)
120: || t.equals(Integer.TYPE)) {
121: return new Integer(s);
122: } else if (t.equals(Float.class) || t.equals(Float.TYPE)) {
123: return new Float(s);
124: } else if (t.equals(Long.class) || t.equals(Long.TYPE)) {
125: return new Long(s);
126: } else if (t.equals(Double.class) || t.equals(Double.TYPE)) {
127: return new Double(s);
128: } else if (t.equals(String.class)) {
129: return s;
130: } else if (t.equals(java.io.File.class)) {
131: return new java.io.File(s);
132: }
133: } catch (Exception ex) {
134: throw new JasperException(ex);
135: }
136: return s;
137: }
138:
139: // __end convertMethod
140:
141: // __begin introspectMethod
142: public static void introspect(Object bean, ServletRequest request)
143: throws JasperException {
144: Enumeration e = request.getParameterNames();
145: while (e.hasMoreElements()) {
146: String name = (String) e.nextElement();
147: String value = request.getParameter(name);
148: introspecthelper(bean, name, value, request, name, true);
149: }
150: }
151:
152: // __end introspectMethod
153:
154: // __begin introspecthelperMethod
155: public static void introspecthelper(Object bean, String prop,
156: String value, ServletRequest request, String param,
157: boolean ignoreMethodNF) throws JasperException {
158: java.lang.reflect.Method method = null;
159: Class type = null;
160: try {
161: java.beans.BeanInfo info = java.beans.Introspector
162: .getBeanInfo(bean.getClass());
163: if (info != null) {
164: java.beans.PropertyDescriptor pd[] = info
165: .getPropertyDescriptors();
166: String decapProp = java.beans.Introspector
167: .decapitalize(prop);
168: for (int i = 0; i < pd.length; i++) {
169: if (pd[i].getName().equals(decapProp)) {
170: method = pd[i].getWriteMethod();
171: type = pd[i].getPropertyType();
172: break;
173: }
174: }
175: }
176: if (method != null) {
177: if (type.isArray()) {
178: if (request == null) {
179: throw new JasperException(
180: Constants
181: .getString(
182: "jsp.error.beans.setproperty.noindexset",
183: new Object[] {}));
184: }
185: ;
186: Class t = type.getComponentType();
187: String[] values = request.getParameterValues(param);
188: //XXX Please check.
189: if (values == null)
190: return;
191: if (t.equals(String.class)) {
192: method.invoke(bean, new Object[] { values });
193: } else {
194: Object tmpval = null;
195: createTypedArray(bean, method, values, t);
196: }
197: } else {
198: if (value == null
199: || (param != null && value.equals("")))
200: return;
201: Object oval = convert(value, type);
202: if (oval != null)
203: method.invoke(bean, new Object[] { oval });
204: }
205: }
206: } catch (Exception ex) {
207: throw new JasperException(ex);
208: }
209: if (!ignoreMethodNF && (method == null)) {
210: if (type == null) {
211: throw new JasperException(Constants.getString(
212: "jsp.error.beans.noproperty", new Object[] {
213: prop, bean.getClass().getName() }));
214: } else {
215: throw new JasperException(Constants
216: .getString(
217: "jsp.error.beans.nomethod.setproperty",
218: new Object[] { prop,
219: bean.getClass().getName() }));
220: }
221: }
222: }
223:
224: // __end introspecthelperMethod
225:
226: //-------------------------------------------------------------------
227: // functions to convert builtin Java data types to string.
228: //-------------------------------------------------------------------
229: // __begin toStringMethod
230: public static String toString(Object o) {
231: return (o == null) ? "" : o.toString();
232: }
233:
234: public static String toString(byte b) {
235: return new Byte(b).toString();
236: }
237:
238: public static String toString(boolean b) {
239: return new Boolean(b).toString();
240: }
241:
242: public static String toString(short s) {
243: return new Short(s).toString();
244: }
245:
246: public static String toString(int i) {
247: return new Integer(i).toString();
248: }
249:
250: public static String toString(float f) {
251: return new Float(f).toString();
252: }
253:
254: public static String toString(long l) {
255: return new Long(l).toString();
256: }
257:
258: public static String toString(double d) {
259: return new Double(d).toString();
260: }
261:
262: public static String toString(char c) {
263: return new Character(c).toString();
264: }
265:
266: // __end toStringMethod
267:
268: /**
269: * Create a typed array.
270: * This is a special case where params are passed through
271: * the request and the property is indexed.
272: */
273: public static void createTypedArray(Object bean, Method method,
274: String[] values, Class t) throws JasperException {
275: try {
276: if (t.equals(Integer.class)) {
277: Integer[] tmpval = new Integer[values.length];
278: for (int i = 0; i < values.length; i++)
279: tmpval[i] = new Integer(values[i]);
280: method.invoke(bean, new Object[] { tmpval });
281: } else if (t.equals(Byte.class)) {
282: Byte[] tmpval = new Byte[values.length];
283: for (int i = 0; i < values.length; i++)
284: tmpval[i] = new Byte(values[i]);
285: method.invoke(bean, new Object[] { tmpval });
286: } else if (t.equals(Boolean.class)) {
287: Boolean[] tmpval = new Boolean[values.length];
288: for (int i = 0; i < values.length; i++)
289: tmpval[i] = new Boolean(values[i]);
290: method.invoke(bean, new Object[] { tmpval });
291: } else if (t.equals(Short.class)) {
292: Short[] tmpval = new Short[values.length];
293: for (int i = 0; i < values.length; i++)
294: tmpval[i] = new Short(values[i]);
295: method.invoke(bean, new Object[] { tmpval });
296: } else if (t.equals(Long.class)) {
297: Long[] tmpval = new Long[values.length];
298: for (int i = 0; i < values.length; i++)
299: tmpval[i] = new Long(values[i]);
300: method.invoke(bean, new Object[] { tmpval });
301: } else if (t.equals(Double.class)) {
302: Double[] tmpval = new Double[values.length];
303: for (int i = 0; i < values.length; i++)
304: tmpval[i] = new Double(values[i]);
305: method.invoke(bean, new Object[] { tmpval });
306: } else if (t.equals(Float.class)) {
307: Float[] tmpval = new Float[values.length];
308: for (int i = 0; i < values.length; i++)
309: tmpval[i] = new Float(values[i]);
310: method.invoke(bean, new Object[] { tmpval });
311: } else if (t.equals(Character.class)) {
312: Character[] tmpval = new Character[values.length];
313: for (int i = 0; i < values.length; i++)
314: tmpval[i] = new Character(values[i].charAt(0));
315: method.invoke(bean, new Object[] { tmpval });
316: } else if (t.equals(int.class)) {
317: int[] tmpval = new int[values.length];
318: for (int i = 0; i < values.length; i++)
319: tmpval[i] = Integer.parseInt(values[i]);
320: method.invoke(bean, new Object[] { tmpval });
321: } else if (t.equals(byte.class)) {
322: byte[] tmpval = new byte[values.length];
323: for (int i = 0; i < values.length; i++)
324: tmpval[i] = Byte.parseByte(values[i]);
325: method.invoke(bean, new Object[] { tmpval });
326: } else if (t.equals(boolean.class)) {
327: boolean[] tmpval = new boolean[values.length];
328: for (int i = 0; i < values.length; i++)
329: tmpval[i] = (Boolean.valueOf(values[i]))
330: .booleanValue();
331: method.invoke(bean, new Object[] { tmpval });
332: } else if (t.equals(short.class)) {
333: short[] tmpval = new short[values.length];
334: for (int i = 0; i < values.length; i++)
335: tmpval[i] = Short.parseShort(values[i]);
336: method.invoke(bean, new Object[] { tmpval });
337: } else if (t.equals(long.class)) {
338: long[] tmpval = new long[values.length];
339: for (int i = 0; i < values.length; i++)
340: tmpval[i] = Long.parseLong(values[i]);
341: method.invoke(bean, new Object[] { tmpval });
342: } else if (t.equals(double.class)) {
343: double[] tmpval = new double[values.length];
344: for (int i = 0; i < values.length; i++)
345: tmpval[i] = Double.valueOf(values[i]).doubleValue();
346: method.invoke(bean, new Object[] { tmpval });
347: } else if (t.equals(float.class)) {
348: float[] tmpval = new float[values.length];
349: for (int i = 0; i < values.length; i++)
350: tmpval[i] = Float.valueOf(values[i]).floatValue();
351: method.invoke(bean, new Object[] { tmpval });
352: } else if (t.equals(char.class)) {
353: char[] tmpval = new char[values.length];
354: for (int i = 0; i < values.length; i++)
355: tmpval[i] = values[i].charAt(0);
356: method.invoke(bean, new Object[] { tmpval });
357: }
358: } catch (Exception ex) {
359: throw new JasperException("error in invoking method");
360: }
361:
362: }
363:
364: /**
365: * Escape special shell characters.
366: * @param unescString The string to shell-escape
367: * @return The escaped shell string.
368: */
369:
370: public static String escapeQueryString(String unescString) {
371: if (unescString == null)
372: return null;
373:
374: String escString = "";
375: String shellSpChars = "&;`'\"|*?~<>^()[]{}$\\\n";
376:
377: for (int index = 0; index < unescString.length(); index++) {
378: char nextChar = unescString.charAt(index);
379:
380: if (shellSpChars.indexOf(nextChar) != -1)
381: escString += "\\";
382:
383: escString += nextChar;
384: }
385: return escString;
386: }
387:
388: /**
389: * Decode an URL formatted string.
390: * @param s The string to decode.
391: * @return The decoded string.
392: */
393:
394: public static String decode(String encoded) {
395: // speedily leave if we're not needed
396: if (encoded == null)
397: return null;
398: if (encoded.indexOf('%') == -1 && encoded.indexOf('+') == -1)
399: return encoded;
400:
401: //allocate the buffer - use byte[] to avoid calls to new.
402: byte holdbuffer[] = new byte[encoded.length()];
403:
404: char holdchar;
405: int bufcount = 0;
406:
407: for (int count = 0; count < encoded.length(); count++) {
408: char cur = encoded.charAt(count);
409: if (cur == '%') {
410: holdbuffer[bufcount++] = (byte) Integer.parseInt(
411: encoded.substring(count + 1, count + 3), 16);
412: if (count + 2 >= encoded.length())
413: count = encoded.length();
414: else
415: count += 2;
416: } else if (cur == '+') {
417: holdbuffer[bufcount++] = (byte) ' ';
418: } else {
419: holdbuffer[bufcount++] = (byte) cur;
420: }
421: }
422: // REVISIT -- remedy for Deprecated warning.
423: //return new String(holdbuffer,0,0,bufcount);
424: return new String(holdbuffer, 0, bufcount);
425: }
426:
427: // __begin lookupReadMethodMethod
428: public static Object handleGetProperty(Object o, String prop)
429: throws JasperException {
430: if (o == null) {
431: throw new JasperException(Constants.getString(
432: "jsp.error.beans.nullbean", new Object[] {}));
433: }
434: Object value = null;
435: try {
436: java.lang.reflect.Method method = getReadMethod(o
437: .getClass(), prop);
438: value = method.invoke(o, null);
439: } catch (Exception ex) {
440: throw new JasperException(ex);
441: }
442: return value;
443: }
444:
445: // __end lookupReadMethodMethod
446:
447: public static void handleSetProperty(Object bean, String prop,
448: Object value) throws JasperException {
449: try {
450: Method method = getWriteMethod(bean.getClass(), prop);
451: method.invoke(bean, new Object[] { value });
452: } catch (Exception ex) {
453: throw new JasperException(ex);
454: }
455: }
456:
457: public static void handleSetProperty(Object bean, String prop,
458: int value) throws JasperException {
459: try {
460: Method method = getWriteMethod(bean.getClass(), prop);
461: method.invoke(bean, new Object[] { new Integer(value) });
462: } catch (Exception ex) {
463: throw new JasperException(ex);
464: }
465: }
466:
467: public static void handleSetProperty(Object bean, String prop,
468: short value) throws JasperException {
469: try {
470: Method method = getWriteMethod(bean.getClass(), prop);
471: method.invoke(bean, new Object[] { new Short(value) });
472: } catch (Exception ex) {
473: throw new JasperException(ex);
474: }
475: }
476:
477: public static void handleSetProperty(Object bean, String prop,
478: long value) throws JasperException {
479: try {
480: Method method = getWriteMethod(bean.getClass(), prop);
481: method.invoke(bean, new Object[] { new Long(value) });
482: } catch (Exception ex) {
483: throw new JasperException(ex);
484: }
485: }
486:
487: public static void handleSetProperty(Object bean, String prop,
488: double value) throws JasperException {
489: try {
490: Method method = getWriteMethod(bean.getClass(), prop);
491: method.invoke(bean, new Object[] { new Double(value) });
492: } catch (Exception ex) {
493: throw new JasperException(ex);
494: }
495: }
496:
497: public static void handleSetProperty(Object bean, String prop,
498: float value) throws JasperException {
499: try {
500: Method method = getWriteMethod(bean.getClass(), prop);
501: method.invoke(bean, new Object[] { new Float(value) });
502: } catch (Exception ex) {
503: throw new JasperException(ex);
504: }
505: }
506:
507: public static void handleSetProperty(Object bean, String prop,
508: char value) throws JasperException {
509: try {
510: Method method = getWriteMethod(bean.getClass(), prop);
511: method.invoke(bean, new Object[] { new Character(value) });
512: } catch (Exception ex) {
513: throw new JasperException(ex);
514: }
515: }
516:
517: public static void handleSetProperty(Object bean, String prop,
518: byte value) throws JasperException {
519: try {
520: Method method = getWriteMethod(bean.getClass(), prop);
521: method.invoke(bean, new Object[] { new Byte(value) });
522: } catch (Exception ex) {
523: throw new JasperException(ex);
524: }
525: }
526:
527: public static void handleSetProperty(Object bean, String prop,
528: boolean value) throws JasperException {
529: try {
530: Method method = getWriteMethod(bean.getClass(), prop);
531: method.invoke(bean, new Object[] { new Boolean(value) });
532: } catch (Exception ex) {
533: throw new JasperException(ex);
534: }
535: }
536:
537: public static java.lang.reflect.Method getWriteMethod(
538: Class beanClass, String prop) throws JasperException {
539: java.lang.reflect.Method method = null;
540: Class type = null;
541: try {
542: java.beans.BeanInfo info = java.beans.Introspector
543: .getBeanInfo(beanClass);
544: if (info != null) {
545: java.beans.PropertyDescriptor pd[] = info
546: .getPropertyDescriptors();
547: String decapProp = java.beans.Introspector
548: .decapitalize(prop);
549: for (int i = 0; i < pd.length; i++) {
550: if (pd[i].getName().equals(decapProp)) {
551: method = pd[i].getWriteMethod();
552: type = pd[i].getPropertyType();
553: break;
554: }
555: }
556: } else {
557: // just in case introspection silently fails.
558: throw new JasperException(Constants.getString(
559: "jsp.error.beans.nobeaninfo",
560: new Object[] { beanClass.getName() }));
561: }
562: } catch (Exception ex) {
563: throw new JasperException(ex);
564: }
565: if (method == null) {
566: if (type == null) {
567: throw new JasperException(Constants.getString(
568: "jsp.error.beans.noproperty", new Object[] {
569: prop, beanClass.getName() }));
570: } else {
571: throw new JasperException(Constants.getString(
572: "jsp.error.beans.nomethod.setproperty",
573: new Object[] { prop, beanClass.getName() }));
574: }
575: }
576: return method;
577: }
578:
579: public static java.lang.reflect.Method getReadMethod(
580: Class beanClass, String prop) throws JasperException {
581: java.lang.reflect.Method method = null;
582: Class type = null;
583: try {
584: java.beans.BeanInfo info = java.beans.Introspector
585: .getBeanInfo(beanClass);
586: if (info != null) {
587: java.beans.PropertyDescriptor pd[] = info
588: .getPropertyDescriptors();
589: String decapProp = java.beans.Introspector
590: .decapitalize(prop);
591: for (int i = 0; i < pd.length; i++) {
592: if (pd[i].getName().equals(decapProp)) {
593: method = pd[i].getReadMethod();
594: type = pd[i].getPropertyType();
595: break;
596: }
597: }
598: } else {
599: // just in case introspection silently fails.
600: throw new JasperException(Constants.getString(
601: "jsp.error.beans.nobeaninfo",
602: new Object[] { beanClass.getName() }));
603: }
604: } catch (Exception ex) {
605: throw new JasperException(ex);
606: }
607: if (method == null) {
608: if (type == null) {
609: throw new JasperException(Constants.getString(
610: "jsp.error.beans.noproperty", new Object[] {
611: prop, beanClass.getName() }));
612: } else {
613: throw new JasperException(Constants.getString(
614: "jsp.error.beans.nomethod", new Object[] {
615: prop, beanClass.getName() }));
616: }
617: }
618:
619: return method;
620: }
621:
622: }
|