001: /*
002: * $Id: PropertyResolver.java 4710 2006-03-02 00:46:15 -0800 (Thu, 02 Mar 2006)
003: * eelco12 $ $Revision: 461180 $ $Date: 2006-03-02 00:46:15 -0800 (Thu, 02 Mar
004: * 2006) $
005: *
006: * ==============================================================================
007: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
008: * use this file except in compliance with the License. You may obtain a copy of
009: * the License at
010: *
011: * http://www.apache.org/licenses/LICENSE-2.0
012: *
013: * Unless required by applicable law or agreed to in writing, software
014: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
015: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
016: * License for the specific language governing permissions and limitations under
017: * the License.
018: */
019: package wicket.util.lang;
020:
021: import java.lang.reflect.Array;
022: import java.lang.reflect.Field;
023: import java.lang.reflect.InvocationTargetException;
024: import java.lang.reflect.Method;
025: import java.util.List;
026: import java.util.Map;
027:
028: import org.apache.commons.logging.Log;
029: import org.apache.commons.logging.LogFactory;
030:
031: import wicket.Session;
032: import wicket.WicketRuntimeException;
033: import wicket.util.concurrent.ConcurrentHashMap;
034: import wicket.util.convert.ConversionException;
035: import wicket.util.convert.IConverter;
036: import wicket.util.string.Strings;
037:
038: /**
039: * This class parses expressions to lookup or set a value on the object that is
040: * given. <br/> The supported expressions are:
041: * <p>
042: * "property": This can can then be a bean property with get and set method. Or
043: * if a map is given as an object it will be lookup with the property as a key
044: * when there is not get method for that property. <p/>
045: * <p>
046: * "property1.property2": Both properties are lookup as written above. If
047: * property1 evaluates to null then if there is a setMethod (or if it is a map)
048: * and the Class of the property has a default constructor then the object will
049: * be constructed and set on the object. <p/>
050: * <p>
051: * "property.index": If the property is a List or Array then the second property
052: * can be a index on that list like: 'mylist.0' this expression will also map on
053: * a getProperty(index) or setProperty(index,value) methods. If the object is a
054: * List then the list will grow automaticaly if the index is greater then the
055: * size <p/>
056: * <p>
057: * Index or map properties can also be written as: "property[index]" or
058: * "property[key]" <p/>
059: *
060: * @author jcompagner
061: */
062: public final class PropertyResolver {
063: private final static Map classesToGetAndSetters = new ConcurrentHashMap(
064: 64);
065:
066: /** Log. */
067: private static final Log log = LogFactory
068: .getLog(PropertyResolver.class);
069:
070: /**
071: * Looksup the value from the object with the given expression. If the
072: * expresion, the object itself or one property evalutes to null then a null
073: * will be returned.
074: *
075: * @param expression
076: * The expression string with the property to be lookup.
077: * @param object
078: * The object which is evaluated.
079: * @return The value that is evaluted. Null something in the expression
080: * evaluted to null.
081: */
082: public final static Object getValue(final String expression,
083: final Object object) {
084: if (expression == null || expression.equals("")
085: || object == null) {
086: return object;
087: }
088:
089: ObjectAndGetSetter getter = getObjectAndGetSetter(expression,
090: object, false);
091: if (getter == null) {
092: return null;
093: }
094: return getter.getValue();
095:
096: }
097:
098: /**
099: * Set the value on the object with the given expression. If the expression
100: * can't be evaluated then a WicketRuntimeException will be thrown. If a
101: * null object is encounted then it will try to generate it by calling the
102: * default constructor and set it on the object.
103: *
104: * The value will be tried to convert to the right type with the given
105: * converter.
106: *
107: * @param expression
108: * The expression string with the property to be set.
109: * @param object
110: * The object which is evaluated to set the value on.
111: * @param value
112: * The value to set.
113: * @param converter
114: * The convertor to convert the value if needed to the right
115: * type.
116: */
117: public final static void setValue(final String expression,
118: final Object object, Object value, IConverter converter) {
119: if (expression == null || expression.equals("")) {
120: throw new WicketRuntimeException(
121: "Empty expression setting value: " + value
122: + " on object: " + object);
123: }
124: if (object == null) {
125: throw new WicketRuntimeException(
126: "Null object setting value: " + value
127: + " with expression: " + expression);
128: }
129:
130: ObjectAndGetSetter setter = getObjectAndGetSetter(expression,
131: object, true);
132: if (setter == null) {
133: throw new WicketRuntimeException(
134: "Null object returned for expression: "
135: + expression + " for setting value: "
136: + value + " on: " + object);
137: }
138: setter.setValue(value, converter == null ? Session.get()
139: .getConverter() : converter);
140: }
141:
142: private static ObjectAndGetSetter getObjectAndGetSetter(
143: final String expression, final Object object,
144: boolean tryToCreateNull) {
145: final String expressionBracketsSeperated = Strings.replaceAll(
146: expression, "[", ".[").toString();
147: int index = expressionBracketsSeperated.indexOf('.');
148: int lastIndex = 0;
149: Object value = object;
150: Class clz = value.getClass();
151: String exp = expressionBracketsSeperated;
152: while (index != -1) {
153: exp = expressionBracketsSeperated.substring(lastIndex,
154: index);
155: IGetAndSet getAndSetter = null;
156: try {
157: getAndSetter = getGetAndSetter(exp, clz);
158: } catch (WicketRuntimeException ex) {
159:
160: // expression by it self can't be found. try to find a
161: // setPropertyByIndex(int,value) method
162: index = expressionBracketsSeperated.indexOf('.',
163: index + 1);
164: if (index != -1) {
165: String indexExpression = expressionBracketsSeperated
166: .substring(lastIndex, index);
167: getAndSetter = getGetAndSetter(indexExpression, clz);
168: } else {
169: exp = expressionBracketsSeperated
170: .substring(lastIndex);
171: break;
172: }
173: }
174: Object newValue = getAndSetter.getValue(value);
175: if (newValue == null) {
176: if (tryToCreateNull) {
177: newValue = getAndSetter.newValue(value);
178: if (newValue == null) {
179: return null;
180: }
181: } else {
182: return null;
183: }
184: }
185: value = newValue;
186: lastIndex = index + 1;
187: index = expressionBracketsSeperated.indexOf('.', lastIndex);
188: clz = value.getClass();
189: if (index == -1) {
190: exp = expressionBracketsSeperated.substring(lastIndex);
191: break;
192: }
193: }
194: IGetAndSet getAndSetter = getGetAndSetter(exp, clz);
195: return new ObjectAndGetSetter(getAndSetter, value);
196: }
197:
198: private final static IGetAndSet getGetAndSetter(String exp,
199: Class clz) {
200: Map getAndSetters = (Map) classesToGetAndSetters.get(clz);
201: if (getAndSetters == null) {
202: getAndSetters = new ConcurrentHashMap(8);
203: classesToGetAndSetters.put(clz, getAndSetters);
204: }
205:
206: IGetAndSet getAndSetter = (IGetAndSet) getAndSetters.get(exp);
207: if (getAndSetter == null) {
208: Method method = null;
209: Field field = null;
210: if (exp.startsWith("[")) {
211: // if expression begins with [ skip method finding and use it as
212: // a key/index lookup on a map.
213: exp = exp.substring(1, exp.length() - 1);
214: } else if (exp.endsWith("()")) {
215: // if expression ends with (), don't test for setters just skip
216: // directly to method finding.
217: method = findMethod(clz, exp);
218: } else {
219: method = findGetter(clz, exp);
220: if (method == null) {
221: // find field.
222: field = findField(clz, exp);
223: }
224: }
225: if (method == null && field == null) {
226: if (List.class.isAssignableFrom(clz)) {
227: try {
228: int index = Integer.parseInt(exp);
229: getAndSetter = new ListGetSet(index);
230: } catch (NumberFormatException ex) {
231: // can't parse the exp als a index maybe the exp was a
232: // method.
233: method = findMethod(clz, exp);
234: if (method != null) {
235: getAndSetter = new MethodGetAndSet(method);
236: } else {
237: throw new WicketRuntimeException(
238: "The expression '"
239: + exp
240: + "' is neither an index nor is it a method for the list "
241: + clz);
242: }
243: }
244: } else if (Map.class.isAssignableFrom(clz)) {
245: getAndSetter = new MapGetSet(exp);
246: } else if (clz.isArray()) {
247: try {
248: int index = Integer.parseInt(exp);
249: getAndSetter = new ArrayGetSet(index);
250: } catch (NumberFormatException ex) {
251: if (exp.equals("length") || exp.equals("size")) {
252: getAndSetter = new ArrayLengthGetSet();
253: } else {
254: throw new WicketRuntimeException(
255: "can't parse the exp "
256: + exp
257: + " as an index for an array lookup");
258: }
259: }
260: } else {
261: method = findMethod(clz, exp);
262: if (method == null) {
263: int index = exp.indexOf('.');
264: if (index != -1) {
265: String propertyName = exp.substring(0,
266: index);
267: String propertyIndex = exp
268: .substring(index + 1);
269: try {
270:
271: int parsedIndex = Integer
272: .parseInt(propertyIndex);
273: // if so then it could be a
274: // getPropertyIndex(int)
275: // and setPropertyIndex(int, object)
276: String name = Character
277: .toUpperCase(propertyName
278: .charAt(0))
279: + propertyName.substring(1);
280: method = clz.getMethod("get" + name,
281: new Class[] { int.class });
282: getAndSetter = new ArrayPropertyGetSet(
283: method, parsedIndex);
284:
285: } catch (Exception e) {
286: throw new WicketRuntimeException(
287: "no get method defined for class: "
288: + clz + " expression: "
289: + propertyName);
290: }
291: } else {
292: // We do not look for a public FIELD because that is
293: // not good
294: // programming with beans patterns
295: throw new WicketRuntimeException(
296: "No get method defined for class: "
297: + clz + " expression: "
298: + exp);
299: }
300: } else {
301: getAndSetter = new MethodGetAndSet(method);
302: }
303: }
304: } else if (field != null) {
305: getAndSetter = new FieldGetAndSetter(field);
306: } else {
307: getAndSetter = new MethodGetAndSet(method);
308: }
309: getAndSetters.put(exp, getAndSetter);
310: }
311: return getAndSetter;
312: }
313:
314: /**
315: * @param clz
316: * @param expression
317: * @return introspected field
318: */
319: private static Field findField(Class clz, String expression) {
320: Field field = null;
321: try {
322: field = clz.getField(expression);
323: } catch (Exception e) {
324: log.debug("Cannot find field " + clz + "." + expression, e);
325: }
326: return field;
327: }
328:
329: /**
330: * @param clz
331: * @param expression
332: * @return The method for the expression null if not found
333: */
334: private final static Method findGetter(Class clz, String expression) {
335: String name = Character.toUpperCase(expression.charAt(0))
336: + expression.substring(1);
337: Method method = null;
338: try {
339: method = clz.getMethod("get" + name, null);
340: } catch (Exception e) {
341: }
342: if (method == null) {
343: try {
344: method = clz.getMethod("is" + name, null);
345: } catch (Exception e) {
346: log.debug("Cannot find getter " + clz + "."
347: + expression, e);
348: }
349: }
350: return method;
351: }
352:
353: private final static Method findMethod(Class clz, String expression) {
354: if (expression.endsWith("()")) {
355: expression = expression.substring(0,
356: expression.length() - 2);
357: }
358: Method method = null;
359: try {
360: method = clz.getMethod(expression, null);
361: } catch (Exception e) {
362: log
363: .debug("Cannot find method " + clz + "."
364: + expression, e);
365: }
366: return method;
367: }
368:
369: /**
370: * Utility class: instantiation not allowed.
371: */
372: private PropertyResolver() {
373: }
374:
375: /**
376: * @author jcompagner
377: *
378: */
379: private final static class ObjectAndGetSetter {
380:
381: private final IGetAndSet getAndSetter;
382: private final Object value;
383:
384: /**
385: * @param getAndSetter
386: * @param value
387: */
388: public ObjectAndGetSetter(IGetAndSet getAndSetter, Object value) {
389: this .getAndSetter = getAndSetter;
390: this .value = value;
391: }
392:
393: /**
394: * @param value
395: * @param converter
396: */
397: public void setValue(Object value, IConverter converter) {
398: getAndSetter.setValue(this .value, value, converter);
399: }
400:
401: /**
402: * @return The value
403: */
404: public Object getValue() {
405: return getAndSetter.getValue(value);
406: }
407:
408: }
409:
410: private static interface IGetAndSet {
411: /**
412: * @param object
413: * The object where the value must be taken from.
414: *
415: * @return The value of this property
416: */
417: public Object getValue(final Object object);
418:
419: /**
420: * @param object
421: * The object where the new value must be set on.
422: *
423: * @return The new value for the property that is set back on that
424: * object.
425: */
426: public Object newValue(Object object);
427:
428: /**
429: * @param object
430: * @param value
431: * @param converter
432: */
433: public void setValue(final Object object, final Object value,
434: IConverter converter);
435:
436: }
437:
438: private static final class MapGetSet implements IGetAndSet {
439: final private String key;
440:
441: MapGetSet(String key) {
442: this .key = key;
443: }
444:
445: /**
446: * @see wicket.util.lang.PropertyResolver.IGetAndSet#getValue(java.lang.Object)
447: */
448: public Object getValue(Object object) {
449: return ((Map) object).get(key);
450: }
451:
452: /**
453: * @see wicket.util.lang.PropertyResolver.IGetAndSet#setValue(java.lang.Object,
454: * java.lang.Object, wicket.util.convert.IConverter)
455: */
456: public void setValue(Object object, Object value,
457: IConverter converter) {
458: ((Map) object).put(key, value);
459: }
460:
461: /**
462: * @see wicket.util.lang.PropertyResolver.IGetAndSet#newValue(Object)
463: */
464: public Object newValue(Object object) {
465: // Map can't make a newValue or should it look what is more in the
466: // map and try to make one of the class if finds?
467: return null;
468: }
469: }
470:
471: private static final class ListGetSet implements IGetAndSet {
472: final private int index;
473:
474: ListGetSet(int index) {
475: this .index = index;
476: }
477:
478: /**
479: * @see wicket.util.lang.PropertyResolver.IGetAndSet#getValue(java.lang.Object)
480: */
481: public Object getValue(Object object) {
482: return ((List) object).get(index);
483: }
484:
485: /**
486: * @see wicket.util.lang.PropertyResolver.IGetAndSet#setValue(java.lang.Object,
487: * java.lang.Object, wicket.util.convert.IConverter)
488: */
489: public void setValue(Object object, Object value,
490: IConverter converter) {
491: List lst = (List) object;
492:
493: if (lst.size() > index) {
494: lst.set(index, value);
495: } else if (lst.size() == index) {
496: lst.add(value);
497: } else {
498: while (lst.size() < index) {
499: lst.add(null);
500: }
501: lst.add(value);
502: }
503: }
504:
505: /**
506: * @see wicket.util.lang.PropertyResolver.IGetAndSet#newValue(Object)
507: */
508: public Object newValue(Object object) {
509: // List can't make a newValue or should it look what is more in the
510: // list and try to make one of the class if finds?
511: return null;
512: }
513: }
514:
515: private static final class ArrayGetSet implements IGetAndSet {
516: final private int index;
517:
518: ArrayGetSet(int index) {
519: this .index = index;
520: }
521:
522: /**
523: * @see wicket.util.lang.PropertyResolver.IGetAndSet#getValue(java.lang.Object)
524: */
525: public Object getValue(Object object) {
526: return Array.get(object, index);
527: }
528:
529: /**
530: * @see wicket.util.lang.PropertyResolver.IGetAndSet#setValue(java.lang.Object,
531: * java.lang.Object, wicket.util.convert.IConverter)
532: */
533: public void setValue(Object object, Object value,
534: IConverter converter) {
535: value = converter.convert(value, object.getClass()
536: .getComponentType());
537: Array.set(object, index, value);
538: }
539:
540: /**
541: * @see wicket.util.lang.PropertyResolver.IGetAndSet#newValue(java.lang.Object)
542: */
543: public Object newValue(Object object) {
544: Class clz = object.getClass().getComponentType();
545: Object value = null;
546: try {
547: value = clz.newInstance();
548: Array.set(object, index, value);
549: } catch (Exception e) {
550: log
551: .warn(
552: "Cannot set new value "
553: + value
554: + " at index "
555: + index
556: + " for array holding elements of class "
557: + clz, e);
558: }
559: return value;
560: }
561: }
562:
563: private static final class ArrayLengthGetSet implements IGetAndSet {
564: ArrayLengthGetSet() {
565: }
566:
567: /**
568: * @see wicket.util.lang.PropertyResolver.IGetAndSet#getValue(java.lang.Object)
569: */
570: public Object getValue(Object object) {
571: return new Integer(Array.getLength(object));
572: }
573:
574: /**
575: * @see wicket.util.lang.PropertyResolver.IGetAndSet#setValue(java.lang.Object,
576: * java.lang.Object, wicket.util.convert.IConverter)
577: */
578: public void setValue(Object object, Object value,
579: IConverter converter) {
580: throw new WicketRuntimeException(
581: "Cant set the length on an array");
582: }
583:
584: /**
585: * @see wicket.util.lang.PropertyResolver.IGetAndSet#newValue(java.lang.Object)
586: */
587: public Object newValue(Object object) {
588: throw new WicketRuntimeException(
589: "Cant get a new value from a length of an array");
590: }
591: }
592:
593: private static final class ArrayPropertyGetSet implements
594: IGetAndSet {
595: final private Integer index;
596: final private Method getMethod;
597: private Method setMethod;
598:
599: ArrayPropertyGetSet(Method method, int index) {
600: this .index = new Integer(index);
601: this .getMethod = method;
602: }
603:
604: private final static Method findSetter(Method getMethod,
605: Class clz) {
606: String name = getMethod.getName();
607: name = "set" + name.substring(3);
608: try {
609: return clz.getMethod(name, new Class[] { int.class,
610: getMethod.getReturnType() });
611: } catch (Exception e) {
612: log.debug("Cannot find setter method corresponding to "
613: + getMethod, e);
614: }
615: return null;
616: }
617:
618: /**
619: * @see wicket.util.lang.PropertyResolver.IGetAndSet#getValue(java.lang.Object)
620: */
621: public Object getValue(Object object) {
622: Object ret = null;
623: try {
624: ret = getMethod.invoke(object, new Object[] { index });
625: } catch (InvocationTargetException ex) {
626: throw new WicketRuntimeException(
627: "Error calling index property method: "
628: + getMethod + " on object: " + object,
629: ex.getCause());
630: } catch (Exception ex) {
631: throw new WicketRuntimeException(
632: "Error calling index property method: "
633: + getMethod + " on object: " + object,
634: ex);
635: }
636: return ret;
637: }
638:
639: /**
640: * @see wicket.util.lang.PropertyResolver.IGetAndSet#setValue(java.lang.Object,
641: * java.lang.Object, wicket.util.convert.IConverter)
642: */
643: public void setValue(Object object, Object value,
644: IConverter converter) {
645: if (setMethod == null) {
646: setMethod = findSetter(getMethod, object.getClass());
647: }
648: if (setMethod != null) {
649: Object converted = converter.convert(value, getMethod
650: .getReturnType());
651: if (converted == null && value != null) {
652: throw new ConversionException(
653: "Can't convert value: " + value
654: + " to class: "
655: + getMethod.getReturnType()
656: + " for setting it on " + object);
657: }
658: try {
659: setMethod.invoke(object, new Object[] { index,
660: converted });
661: } catch (InvocationTargetException ex) {
662: throw new WicketRuntimeException(
663: "Error index property calling method: "
664: + setMethod + " on object: "
665: + object, ex.getCause());
666: } catch (Exception ex) {
667: throw new WicketRuntimeException(
668: "Error index property calling method: "
669: + setMethod + " on object: "
670: + object, ex);
671: }
672: } else {
673: throw new WicketRuntimeException(
674: "no set method defined for value: " + value
675: + " on object: " + object);
676: }
677: }
678:
679: /**
680: * @see wicket.util.lang.PropertyResolver.IGetAndSet#newValue(java.lang.Object)
681: */
682: public Object newValue(Object object) {
683: if (setMethod == null) {
684: setMethod = findSetter(getMethod, object.getClass());
685: }
686:
687: if (setMethod == null) {
688: log.warn("Null setMethod");
689: return null;
690: }
691:
692: Class clz = getMethod.getReturnType();
693: Object value = null;
694: try {
695: value = clz.newInstance();
696: setMethod.invoke(object, new Object[] { index, value });
697: } catch (Exception e) {
698: log.warn("Cannot set new value " + value + " at index "
699: + index, e);
700: }
701: return value;
702: }
703: }
704:
705: private static final class MethodGetAndSet implements IGetAndSet {
706: private Method getMethod;
707: private Method setMethod;
708:
709: MethodGetAndSet(Method getMethod) {
710: this .getMethod = getMethod;
711: this .getMethod.setAccessible(true);
712: }
713:
714: /**
715: * @see wicket.util.lang.PropertyResolver.IGetAndSet#getValue(java.lang.Object)
716: */
717: public final Object getValue(final Object object) {
718: Object ret = null;
719: try {
720: ret = getMethod.invoke(object, null);
721: } catch (InvocationTargetException ex) {
722: throw new WicketRuntimeException(
723: "Error calling method: " + getMethod
724: + " on object: " + object, ex
725: .getCause());
726: } catch (Exception ex) {
727: throw new WicketRuntimeException(
728: "Error calling method: " + getMethod
729: + " on object: " + object, ex);
730: }
731: return ret;
732: }
733:
734: /**
735: * @param object
736: * @param value
737: * @param converter
738: */
739: public final void setValue(final Object object,
740: final Object value, IConverter converter) {
741: if (setMethod == null) {
742: setMethod = findSetter(getMethod, object.getClass());
743: }
744: if (setMethod != null) {
745: Object converted = converter.convert(value, getMethod
746: .getReturnType());
747: if (converted == null) {
748: if (value != null) {
749: throw new ConversionException(
750: "Can't convert value: " + value
751: + " to class: "
752: + getMethod.getReturnType()
753: + " for setting it on "
754: + object);
755: } else if (getMethod.getReturnType().isPrimitive()) {
756: throw new ConversionException(
757: "Can't convert null value to a primitive class: "
758: + getMethod.getReturnType()
759: + " for setting it on "
760: + object);
761: }
762: }
763: try {
764: setMethod
765: .invoke(object, new Object[] { converted });
766: } catch (InvocationTargetException ex) {
767: throw new WicketRuntimeException(
768: "Error calling method: " + setMethod
769: + " on object: " + object, ex
770: .getCause());
771: } catch (Exception ex) {
772: throw new WicketRuntimeException(
773: "Error calling method: " + setMethod
774: + " on object: " + object, ex);
775: }
776: } else {
777: throw new WicketRuntimeException(
778: "no set method defined for value: " + value
779: + " on object: " + object);
780: }
781: }
782:
783: private final static Method findSetter(Method getMethod,
784: Class clz) {
785: String name = getMethod.getName();
786: if (name.startsWith("get")) {
787: name = "set" + name.substring(3);
788: } else {
789: name = "set" + name.substring(2);
790: }
791: try {
792: Method method = clz.getMethod(name,
793: new Class[] { getMethod.getReturnType() });
794: if (method != null) {
795: method.setAccessible(true);
796: }
797: return method;
798: } catch (Exception e) {
799: log.debug("Cannot find setter corresponding to "
800: + getMethod, e);
801: }
802: return null;
803: }
804:
805: /**
806: * @see wicket.util.lang.PropertyResolver.IGetAndSet#newValue(java.lang.Object)
807: */
808: public Object newValue(Object object) {
809: if (setMethod == null) {
810: setMethod = findSetter(getMethod, object.getClass());
811: }
812:
813: if (setMethod == null) {
814: log.warn("Null setMethod");
815: return null;
816: }
817:
818: Class clz = getMethod.getReturnType();
819: Object value = null;
820: try {
821: value = clz.newInstance();
822: setMethod.invoke(object, new Object[] { value });
823: } catch (Exception e) {
824: log.warn("Cannot set new value " + value, e);
825: }
826: return value;
827: }
828:
829: }
830:
831: /**
832: * @author jcompagner
833: */
834: private static class FieldGetAndSetter implements IGetAndSet {
835:
836: private Field field;
837:
838: /**
839: * Construct.
840: *
841: * @param field
842: */
843: public FieldGetAndSetter(Field field) {
844: super ();
845: this .field = field;
846: this .field.setAccessible(true);
847: }
848:
849: /**
850: * @see wicket.util.lang.PropertyResolver.IGetAndSet#getValue(java.lang.Object)
851: */
852: public Object getValue(Object object) {
853: try {
854: return field.get(object);
855: } catch (Exception ex) {
856: throw new WicketRuntimeException(
857: "Error getting field value of field " + field
858: + " from object " + object, ex);
859: }
860: }
861:
862: /**
863: * @see wicket.util.lang.PropertyResolver.IGetAndSet#newValue(java.lang.Object)
864: */
865: public Object newValue(Object object) {
866: Class clz = field.getType();
867: Object value = null;
868: try {
869: value = clz.newInstance();
870: field.set(object, value);
871: } catch (Exception e) {
872: log.warn("Cannot set field " + field + " to " + value,
873: e);
874: }
875: return value;
876: }
877:
878: /**
879: * @see wicket.util.lang.PropertyResolver.IGetAndSet#setValue(java.lang.Object,
880: * java.lang.Object, wicket.util.convert.IConverter)
881: */
882: public void setValue(Object object, Object value,
883: IConverter converter) {
884: value = converter.convert(value, field.getType());
885: try {
886: field.set(object, value);
887: } catch (Exception ex) {
888: throw new WicketRuntimeException(
889: "Error setting field value of field " + field
890: + " on object " + object + ", value "
891: + value, ex);
892: }
893: }
894: }
895: }
|