Source Code Cross Referenced for PropertyResolver.java in  » J2EE » wicket » org » apache » wicket » util » lang » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » wicket » org.apache.wicket.util.lang 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Licensed to the Apache Software Foundation (ASF) under one or more
0003:         * contributor license agreements.  See the NOTICE file distributed with
0004:         * this work for additional information regarding copyright ownership.
0005:         * The ASF licenses this file to You under the Apache License, Version 2.0
0006:         * (the "License"); you may not use this file except in compliance with
0007:         * the License.  You may obtain a copy of the License at
0008:         *
0009:         *      http://www.apache.org/licenses/LICENSE-2.0
0010:         *
0011:         * Unless required by applicable law or agreed to in writing, software
0012:         * distributed under the License is distributed on an "AS IS" BASIS,
0013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         * See the License for the specific language governing permissions and
0015:         * limitations under the License.
0016:         */
0017:        package org.apache.wicket.util.lang;
0018:
0019:        import java.lang.reflect.Array;
0020:        import java.lang.reflect.Field;
0021:        import java.lang.reflect.InvocationTargetException;
0022:        import java.lang.reflect.Method;
0023:        import java.util.List;
0024:        import java.util.Map;
0025:
0026:        import org.apache.wicket.Application;
0027:        import org.apache.wicket.Session;
0028:        import org.apache.wicket.WicketRuntimeException;
0029:        import org.apache.wicket.util.concurrent.ConcurrentHashMap;
0030:        import org.apache.wicket.util.convert.ConversionException;
0031:        import org.apache.wicket.util.string.Strings;
0032:        import org.slf4j.Logger;
0033:        import org.slf4j.LoggerFactory;
0034:
0035:        /**
0036:         * This class parses expressions to lookup or set a value on the object that is
0037:         * given. <br/> The supported expressions are:
0038:         * <p>
0039:         * "property": This can can then be a bean property with get and set method. Or
0040:         * if a map is given as an object it will be lookup with the property as a key
0041:         * when there is not get method for that property. <p/>
0042:         * <p>
0043:         * "property1.property2": Both properties are lookup as written above. If
0044:         * property1 evaluates to null then if there is a setMethod (or if it is a map)
0045:         * and the Class of the property has a default constructor then the object will
0046:         * be constructed and set on the object. <p/>
0047:         * <p>
0048:         * "property.index": If the property is a List or Array then the second property
0049:         * can be a index on that list like: 'mylist.0' this expression will also map on
0050:         * a getProperty(index) or setProperty(index,value) methods. If the object is a
0051:         * List then the list will grow automaticaly if the index is greater then the
0052:         * size <p/>
0053:         * <p>
0054:         * Index or map properties can also be written as: "property[index]" or
0055:         * "property[key]" <p/>
0056:         * 
0057:         * @author jcompagner
0058:         */
0059:        public final class PropertyResolver {
0060:            private final static int RETURN_NULL = 0;
0061:            private final static int CREATE_NEW_VALUE = 1;
0062:            private final static int RESOLVE_CLASS = 2;
0063:
0064:            private final static Map applicationToClassesToGetAndSetters = new ConcurrentHashMap(
0065:                    2);
0066:
0067:            /** Log. */
0068:            private static final Logger log = LoggerFactory
0069:                    .getLogger(PropertyResolver.class);
0070:
0071:            /**
0072:             * Looksup the value from the object with the given expression. If the
0073:             * expresion, the object itself or one property evalutes to null then a null
0074:             * will be returned.
0075:             * 
0076:             * @param expression
0077:             *            The expression string with the property to be lookup.
0078:             * @param object
0079:             *            The object which is evaluated.
0080:             * @return The value that is evaluted. Null something in the expression
0081:             *         evaluted to null.
0082:             */
0083:            public final static Object getValue(final String expression,
0084:                    final Object object) {
0085:                if (expression == null || expression.equals("")
0086:                        || object == null) {
0087:                    return object;
0088:                }
0089:
0090:                ObjectAndGetSetter getter = getObjectAndGetSetter(expression,
0091:                        object, RETURN_NULL);
0092:                if (getter == null) {
0093:                    return null;
0094:                }
0095:                return getter.getValue();
0096:
0097:            }
0098:
0099:            /**
0100:             * Set the value on the object with the given expression. If the expression
0101:             * can't be evaluated then a WicketRuntimeException will be thrown. If a
0102:             * null object is encounted then it will try to generate it by calling the
0103:             * default constructor and set it on the object.
0104:             * 
0105:             * The value will be tried to convert to the right type with the given
0106:             * converter.
0107:             * 
0108:             * @param expression
0109:             *            The expression string with the property to be set.
0110:             * @param object
0111:             *            The object which is evaluated to set the value on.
0112:             * @param value
0113:             *            The value to set.
0114:             * @param converter
0115:             *            The convertor to convert the value if needed to the right
0116:             *            type.
0117:             */
0118:            public final static void setValue(final String expression,
0119:                    final Object object, Object value,
0120:                    PropertyResolverConverter converter) {
0121:                if (expression == null || expression.equals("")) {
0122:                    throw new WicketRuntimeException(
0123:                            "Empty expression setting value: " + value
0124:                                    + " on object: " + object);
0125:                }
0126:                if (object == null) {
0127:                    throw new WicketRuntimeException(
0128:                            "Null object setting value: " + value
0129:                                    + " with expression: " + expression);
0130:                }
0131:
0132:                ObjectAndGetSetter setter = getObjectAndGetSetter(expression,
0133:                        object, CREATE_NEW_VALUE);
0134:                if (setter == null) {
0135:                    throw new WicketRuntimeException(
0136:                            "Null object returned for expression: "
0137:                                    + expression + " for setting value: "
0138:                                    + value + " on: " + object);
0139:                }
0140:                setter.setValue(value,
0141:                        converter == null ? new PropertyResolverConverter(
0142:                                Application.get().getConverterLocator(),
0143:                                Session.get().getLocale()) : converter);
0144:            }
0145:
0146:            /**
0147:             * @param expression
0148:             * @param object
0149:             * @return class of the target property object
0150:             */
0151:            public final static Class getPropertyClass(String expression,
0152:                    Object object) {
0153:                ObjectAndGetSetter setter = getObjectAndGetSetter(expression,
0154:                        object, RESOLVE_CLASS);
0155:                if (setter == null) {
0156:                    throw new WicketRuntimeException(
0157:                            "Null object returned for expression: "
0158:                                    + expression
0159:                                    + " for getting the target classs of: "
0160:                                    + object);
0161:                }
0162:                return setter.getTargetClass();
0163:            }
0164:
0165:            /**
0166:             * @param expression
0167:             * @param object
0168:             * @return Field for the property expression or null if such field doesn't
0169:             *         exist (only getters and setters)
0170:             */
0171:            public final static Field getPropertyField(String expression,
0172:                    Object object) {
0173:                ObjectAndGetSetter setter = getObjectAndGetSetter(expression,
0174:                        object, RESOLVE_CLASS);
0175:                if (setter == null) {
0176:                    throw new WicketRuntimeException(
0177:                            "Null object returned for expression: "
0178:                                    + expression
0179:                                    + " for getting the target classs of: "
0180:                                    + object);
0181:                }
0182:                return setter.getField();
0183:            }
0184:
0185:            /**
0186:             * @param expression
0187:             * @param object
0188:             * @return Getter method for the property expression or null if such getter
0189:             *         doesn't exist (only field)
0190:             */
0191:            public final static Method getPropertyGetter(String expression,
0192:                    Object object) {
0193:                ObjectAndGetSetter setter = getObjectAndGetSetter(expression,
0194:                        object, RESOLVE_CLASS);
0195:                if (setter == null) {
0196:                    throw new WicketRuntimeException(
0197:                            "Null object returned for expression: "
0198:                                    + expression
0199:                                    + " for getting the target classs of: "
0200:                                    + object);
0201:                }
0202:                return setter.getGetter();
0203:            }
0204:
0205:            /**
0206:             * @param expression
0207:             * @param object
0208:             * @return Setter method for the property expression or null if such setter
0209:             *         doesn't exist (only field)
0210:             */
0211:            public final static Method getPropertySetter(String expression,
0212:                    Object object) {
0213:                ObjectAndGetSetter setter = getObjectAndGetSetter(expression,
0214:                        object, RESOLVE_CLASS);
0215:                if (setter == null) {
0216:                    throw new WicketRuntimeException(
0217:                            "Null object returned for expression: "
0218:                                    + expression
0219:                                    + " for getting the target classs of: "
0220:                                    + object);
0221:                }
0222:                return setter.getSetter();
0223:            }
0224:
0225:            private static ObjectAndGetSetter getObjectAndGetSetter(
0226:                    final String expression, final Object object,
0227:                    int tryToCreateNull) {
0228:                final String expressionBracketsSeperated = Strings.replaceAll(
0229:                        expression, "[", ".[").toString();
0230:                int index = expressionBracketsSeperated.indexOf('.');
0231:                int lastIndex = 0;
0232:                Object value = object;
0233:                Class clz = value.getClass();
0234:                String exp = expressionBracketsSeperated;
0235:                while (index != -1) {
0236:                    exp = expressionBracketsSeperated.substring(lastIndex,
0237:                            index);
0238:                    IGetAndSet getAndSetter = null;
0239:                    try {
0240:                        getAndSetter = getGetAndSetter(exp, clz);
0241:                    } catch (WicketRuntimeException ex) {
0242:
0243:                        // expression by it self can't be found. try to find a
0244:                        // setPropertyByIndex(int,value) method
0245:                        index = expressionBracketsSeperated.indexOf('.',
0246:                                index + 1);
0247:                        if (index != -1) {
0248:                            String indexExpression = expressionBracketsSeperated
0249:                                    .substring(lastIndex, index);
0250:                            getAndSetter = getGetAndSetter(indexExpression, clz);
0251:                        } else {
0252:                            exp = expressionBracketsSeperated
0253:                                    .substring(lastIndex);
0254:                            break;
0255:                        }
0256:                    }
0257:                    Object newValue = null;
0258:                    if (value != null) {
0259:                        newValue = getAndSetter.getValue(value);
0260:                    }
0261:                    if (newValue == null) {
0262:                        if (tryToCreateNull == CREATE_NEW_VALUE) {
0263:                            newValue = getAndSetter.newValue(value);
0264:                            if (newValue == null) {
0265:                                return null;
0266:                            }
0267:                        } else if (tryToCreateNull == RESOLVE_CLASS) {
0268:                            clz = getAndSetter.getTargetClass();
0269:                        } else {
0270:                            return null;
0271:                        }
0272:                    }
0273:                    value = newValue;
0274:                    if (value != null) {
0275:                        // value can be null if we are in the RESOLVE_CLASS
0276:                        clz = value.getClass();
0277:                    }
0278:
0279:                    lastIndex = index + 1;
0280:                    index = expressionBracketsSeperated.indexOf('.', lastIndex);
0281:                    if (index == -1) {
0282:                        exp = expressionBracketsSeperated.substring(lastIndex);
0283:                        break;
0284:                    }
0285:                }
0286:                IGetAndSet getAndSetter = getGetAndSetter(exp, clz);
0287:                return new ObjectAndGetSetter(getAndSetter, value);
0288:            }
0289:
0290:            private final static IGetAndSet getGetAndSetter(String exp,
0291:                    Class clz) {
0292:                Map classesToGetAndSetters = getClassesToGetAndSetters();
0293:                Map getAndSetters = (Map) classesToGetAndSetters.get(clz);
0294:                if (getAndSetters == null) {
0295:                    getAndSetters = new ConcurrentHashMap(8);
0296:                    classesToGetAndSetters.put(clz, getAndSetters);
0297:                }
0298:
0299:                IGetAndSet getAndSetter = (IGetAndSet) getAndSetters.get(exp);
0300:                if (getAndSetter == null) {
0301:                    Method method = null;
0302:                    Field field = null;
0303:                    if (exp.startsWith("[")) {
0304:                        // if expression begins with [ skip method finding and use it as
0305:                        // a key/index lookup on a map.
0306:                        exp = exp.substring(1, exp.length() - 1);
0307:                    } else if (exp.endsWith("()")) {
0308:                        // if expression ends with (), don't test for setters just skip
0309:                        // directly to method finding.
0310:                        method = findMethod(clz, exp);
0311:                    } else {
0312:                        method = findGetter(clz, exp);
0313:                    }
0314:                    if (method == null) {
0315:                        if (List.class.isAssignableFrom(clz)) {
0316:                            try {
0317:                                int index = Integer.parseInt(exp);
0318:                                getAndSetter = new ListGetSet(index);
0319:                            } catch (NumberFormatException ex) {
0320:                                // can't parse the exp als a index maybe the exp was a
0321:                                // method.
0322:                                method = findMethod(clz, exp);
0323:                                if (method != null) {
0324:                                    getAndSetter = new MethodGetAndSet(method,
0325:                                            MethodGetAndSet.findSetter(method,
0326:                                                    clz), null);
0327:                                } else {
0328:                                    field = findField(clz, exp);
0329:                                    if (field != null) {
0330:                                        getAndSetter = new FieldGetAndSetter(
0331:                                                field);
0332:                                    } else {
0333:                                        throw new WicketRuntimeException(
0334:                                                "The expression '"
0335:                                                        + exp
0336:                                                        + "' is neither an index nor is it a method or field for the list "
0337:                                                        + clz);
0338:                                    }
0339:                                }
0340:                            }
0341:                        } else if (Map.class.isAssignableFrom(clz)) {
0342:                            getAndSetter = new MapGetSet(exp);
0343:                        } else if (clz.isArray()) {
0344:                            try {
0345:                                int index = Integer.parseInt(exp);
0346:                                getAndSetter = new ArrayGetSet(clz
0347:                                        .getComponentType(), index);
0348:                            } catch (NumberFormatException ex) {
0349:                                if (exp.equals("length") || exp.equals("size")) {
0350:                                    getAndSetter = new ArrayLengthGetSet();
0351:                                } else {
0352:                                    throw new WicketRuntimeException(
0353:                                            "can't parse the exp "
0354:                                                    + exp
0355:                                                    + " as an index for an array lookup");
0356:                                }
0357:                            }
0358:                        } else {
0359:                            field = findField(clz, exp);
0360:                            if (field == null) {
0361:                                method = findMethod(clz, exp);
0362:                                if (method == null) {
0363:                                    int index = exp.indexOf('.');
0364:                                    if (index != -1) {
0365:                                        String propertyName = exp.substring(0,
0366:                                                index);
0367:                                        String propertyIndex = exp
0368:                                                .substring(index + 1);
0369:                                        try {
0370:
0371:                                            int parsedIndex = Integer
0372:                                                    .parseInt(propertyIndex);
0373:                                            // if so then it could be a
0374:                                            // getPropertyIndex(int)
0375:                                            // and setPropertyIndex(int, object)
0376:                                            String name = Character
0377:                                                    .toUpperCase(propertyName
0378:                                                            .charAt(0))
0379:                                                    + propertyName.substring(1);
0380:                                            method = clz.getMethod(
0381:                                                    "get" + name,
0382:                                                    new Class[] { int.class });
0383:                                            getAndSetter = new ArrayPropertyGetSet(
0384:                                                    method, parsedIndex);
0385:
0386:                                        } catch (Exception e) {
0387:                                            throw new WicketRuntimeException(
0388:                                                    "no get method defined for class: "
0389:                                                            + clz
0390:                                                            + " expression: "
0391:                                                            + propertyName);
0392:                                        }
0393:                                    } else {
0394:                                        // We do not look for a public FIELD because
0395:                                        // that is
0396:                                        // not good
0397:                                        // programming with beans patterns
0398:                                        throw new WicketRuntimeException(
0399:                                                "No get method defined for class: "
0400:                                                        + clz + " expression: "
0401:                                                        + exp);
0402:                                    }
0403:                                } else {
0404:                                    getAndSetter = new MethodGetAndSet(method,
0405:                                            MethodGetAndSet.findSetter(method,
0406:                                                    clz), field);
0407:                                }
0408:                            } else {
0409:                                getAndSetter = new FieldGetAndSetter(field);
0410:                            }
0411:                        }
0412:                    } else {
0413:                        field = findField(clz, exp);
0414:                        getAndSetter = new MethodGetAndSet(method,
0415:                                MethodGetAndSet.findSetter(method, clz), field);
0416:                    }
0417:                    getAndSetters.put(exp, getAndSetter);
0418:                }
0419:                return getAndSetter;
0420:            }
0421:
0422:            /**
0423:             * @param clz
0424:             * @param expression
0425:             * @return introspected field
0426:             */
0427:            private static Field findField(Class clz, String expression) {
0428:                Field field = null;
0429:                try {
0430:                    field = clz.getField(expression);
0431:                } catch (Exception e) {
0432:                    Class tmp = clz;
0433:                    while (tmp != null && tmp != Object.class) {
0434:                        Field[] fields = tmp.getDeclaredFields();
0435:                        for (int i = 0; i < fields.length; i++) {
0436:                            if (fields[i].getName().equals(expression)) {
0437:                                fields[i].setAccessible(true);
0438:                                return fields[i];
0439:                            }
0440:                        }
0441:                        tmp = tmp.getSuperclass();
0442:                    }
0443:                    log.debug("Cannot find field " + clz + "." + expression, e);
0444:                }
0445:                return field;
0446:            }
0447:
0448:            /**
0449:             * @param clz
0450:             * @param expression
0451:             * @return The method for the expression null if not found
0452:             */
0453:            private final static Method findGetter(Class clz, String expression) {
0454:                String name = Character.toUpperCase(expression.charAt(0))
0455:                        + expression.substring(1);
0456:                Method method = null;
0457:                try {
0458:                    method = clz.getMethod("get" + name, null);
0459:                } catch (Exception e) {
0460:                }
0461:                if (method == null) {
0462:                    try {
0463:                        method = clz.getMethod("is" + name, null);
0464:                    } catch (Exception e) {
0465:                        log.debug("Cannot find getter " + clz + "."
0466:                                + expression, e);
0467:                    }
0468:                }
0469:                return method;
0470:            }
0471:
0472:            private final static Method findMethod(Class clz, String expression) {
0473:                if (expression.endsWith("()")) {
0474:                    expression = expression.substring(0,
0475:                            expression.length() - 2);
0476:                }
0477:                Method method = null;
0478:                try {
0479:                    method = clz.getMethod(expression, null);
0480:                } catch (Exception e) {
0481:                    log
0482:                            .debug("Cannot find method " + clz + "."
0483:                                    + expression, e);
0484:                }
0485:                return method;
0486:            }
0487:
0488:            /**
0489:             * Utility class: instantiation not allowed.
0490:             */
0491:            private PropertyResolver() {
0492:            }
0493:
0494:            /**
0495:             * @author jcompagner
0496:             * 
0497:             */
0498:            private final static class ObjectAndGetSetter {
0499:
0500:                private final IGetAndSet getAndSetter;
0501:                private final Object value;
0502:
0503:                /**
0504:                 * @param getAndSetter
0505:                 * @param value
0506:                 */
0507:                public ObjectAndGetSetter(IGetAndSet getAndSetter, Object value) {
0508:                    this .getAndSetter = getAndSetter;
0509:                    this .value = value;
0510:                }
0511:
0512:                /**
0513:                 * @param value
0514:                 * @param converter
0515:                 */
0516:                public void setValue(Object value,
0517:                        PropertyResolverConverter converter) {
0518:                    getAndSetter.setValue(this .value, value, converter);
0519:                }
0520:
0521:                /**
0522:                 * @return The value
0523:                 */
0524:                public Object getValue() {
0525:                    return getAndSetter.getValue(value);
0526:                }
0527:
0528:                /**
0529:                 * @return class of property value
0530:                 */
0531:                public Class getTargetClass() {
0532:                    return getAndSetter.getTargetClass();
0533:                }
0534:
0535:                /**
0536:                 * @return Field or null if no field exists for expression
0537:                 */
0538:                public Field getField() {
0539:                    return getAndSetter.getField();
0540:                }
0541:
0542:                /**
0543:                 * @return Getter method or null if no getter exists for expression
0544:                 */
0545:                public Method getGetter() {
0546:                    return getAndSetter.getGetter();
0547:                }
0548:
0549:                /**
0550:                 * @return Setter method or null if no setter exists for expression
0551:                 */
0552:                public Method getSetter() {
0553:                    return getAndSetter.getSetter();
0554:                }
0555:
0556:            }
0557:
0558:            private static interface IGetAndSet {
0559:                /**
0560:                 * @param object
0561:                 *            The object where the value must be taken from.
0562:                 * 
0563:                 * @return The value of this property
0564:                 */
0565:                public Object getValue(final Object object);
0566:
0567:                /**
0568:                 * @return
0569:                 */
0570:                public Class getTargetClass();
0571:
0572:                /**
0573:                 * @param object
0574:                 *            The object where the new value must be set on.
0575:                 * 
0576:                 * @return The new value for the property that is set back on that
0577:                 *         object.
0578:                 */
0579:                public Object newValue(Object object);
0580:
0581:                /**
0582:                 * @param object
0583:                 * @param value
0584:                 * @param converter
0585:                 */
0586:                public void setValue(final Object object, final Object value,
0587:                        PropertyResolverConverter converter);
0588:
0589:                /**
0590:                 * @return Field or null if there is no field
0591:                 */
0592:                public Field getField();
0593:
0594:                /**
0595:                 * @return Getter method or null if there is no getter
0596:                 */
0597:                public Method getGetter();
0598:
0599:                /**
0600:                 * @return Setter of null if there is no setter
0601:                 */
0602:                public Method getSetter();
0603:            }
0604:
0605:            private static abstract class AbstractGetAndSet implements 
0606:                    IGetAndSet {
0607:                /**
0608:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#getField()
0609:                 */
0610:                public Field getField() {
0611:                    return null;
0612:                }
0613:
0614:                /**
0615:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#getGetter()
0616:                 */
0617:                public Method getGetter() {
0618:                    return null;
0619:                }
0620:
0621:                /**
0622:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#getSetter()
0623:                 */
0624:                public Method getSetter() {
0625:                    return null;
0626:                }
0627:
0628:                /**
0629:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#getTargetClass()
0630:                 */
0631:                public Class getTargetClass() {
0632:                    return null;
0633:                }
0634:            }
0635:
0636:            private static final class MapGetSet extends AbstractGetAndSet {
0637:                final private String key;
0638:
0639:                MapGetSet(String key) {
0640:                    this .key = key;
0641:                }
0642:
0643:                /**
0644:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#getValue(java.lang.Object)
0645:                 */
0646:                public Object getValue(Object object) {
0647:                    return ((Map) object).get(key);
0648:                }
0649:
0650:                /**
0651:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#setValue(java.lang.Object,
0652:                 *      java.lang.Object, org.apache.wicket.util.convert.IConverter)
0653:                 */
0654:                public void setValue(Object object, Object value,
0655:                        PropertyResolverConverter converter) {
0656:                    ((Map) object).put(key, value);
0657:                }
0658:
0659:                /**
0660:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#newValue(Object)
0661:                 */
0662:                public Object newValue(Object object) {
0663:                    // Map can't make a newValue or should it look what is more in the
0664:                    // map and try to make one of the class if finds?
0665:                    return null;
0666:                }
0667:            }
0668:
0669:            private static final class ListGetSet extends AbstractGetAndSet {
0670:                final private int index;
0671:
0672:                ListGetSet(int index) {
0673:                    this .index = index;
0674:                }
0675:
0676:                /**
0677:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#getValue(java.lang.Object)
0678:                 */
0679:                public Object getValue(Object object) {
0680:                    return ((List) object).get(index);
0681:                }
0682:
0683:                /**
0684:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#setValue(java.lang.Object,
0685:                 *      java.lang.Object, org.apache.wicket.util.convert.IConverter)
0686:                 */
0687:                public void setValue(Object object, Object value,
0688:                        PropertyResolverConverter converter) {
0689:                    List lst = (List) object;
0690:
0691:                    if (lst.size() > index) {
0692:                        lst.set(index, value);
0693:                    } else if (lst.size() == index) {
0694:                        lst.add(value);
0695:                    } else {
0696:                        while (lst.size() < index) {
0697:                            lst.add(null);
0698:                        }
0699:                        lst.add(value);
0700:                    }
0701:                }
0702:
0703:                /**
0704:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#newValue(Object)
0705:                 */
0706:                public Object newValue(Object object) {
0707:                    // List can't make a newValue or should it look what is more in the
0708:                    // list and try to make one of the class if finds?
0709:                    return null;
0710:                }
0711:            }
0712:
0713:            private static final class ArrayGetSet extends AbstractGetAndSet {
0714:                private final int index;
0715:                private final Class clzComponentType;
0716:
0717:                ArrayGetSet(Class clzComponentType, int index) {
0718:                    this .clzComponentType = clzComponentType;
0719:                    this .index = index;
0720:                }
0721:
0722:                /**
0723:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#getValue(java.lang.Object)
0724:                 */
0725:                public Object getValue(Object object) {
0726:                    return Array.get(object, index);
0727:                }
0728:
0729:                /**
0730:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#setValue(java.lang.Object,
0731:                 *      java.lang.Object, org.apache.wicket.util.convert.IConverter)
0732:                 */
0733:                public void setValue(Object object, Object value,
0734:                        PropertyResolverConverter converter) {
0735:                    value = converter.convert(value, clzComponentType);
0736:                    Array.set(object, index, value);
0737:                }
0738:
0739:                /**
0740:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#newValue(java.lang.Object)
0741:                 */
0742:                public Object newValue(Object object) {
0743:                    Object value = null;
0744:                    try {
0745:                        value = clzComponentType.newInstance();
0746:                        Array.set(object, index, value);
0747:                    } catch (Exception e) {
0748:                        log.warn("Cannot set new value " + value + " at index "
0749:                                + index
0750:                                + " for array holding elements of class "
0751:                                + clzComponentType, e);
0752:                    }
0753:                    return value;
0754:                }
0755:
0756:                /**
0757:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#getTargetClass()
0758:                 */
0759:                public Class getTargetClass() {
0760:                    return clzComponentType;
0761:                }
0762:            }
0763:
0764:            private static final class ArrayLengthGetSet extends
0765:                    AbstractGetAndSet {
0766:                ArrayLengthGetSet() {
0767:                }
0768:
0769:                /**
0770:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#getValue(java.lang.Object)
0771:                 */
0772:                public Object getValue(Object object) {
0773:                    return new Integer(Array.getLength(object));
0774:                }
0775:
0776:                /**
0777:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#setValue(java.lang.Object,
0778:                 *      java.lang.Object, org.apache.wicket.util.convert.IConverter)
0779:                 */
0780:                public void setValue(Object object, Object value,
0781:                        PropertyResolverConverter converter) {
0782:                    throw new WicketRuntimeException(
0783:                            "Cant set the length on an array");
0784:                }
0785:
0786:                /**
0787:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#newValue(java.lang.Object)
0788:                 */
0789:                public Object newValue(Object object) {
0790:                    throw new WicketRuntimeException(
0791:                            "Cant get a new value from a length of an array");
0792:                }
0793:
0794:                /**
0795:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#getTargetClass()
0796:                 */
0797:                public Class getTargetClass() {
0798:                    return int.class;
0799:                }
0800:            }
0801:
0802:            private static final class ArrayPropertyGetSet extends
0803:                    AbstractGetAndSet {
0804:                final private Integer index;
0805:                final private Method getMethod;
0806:                private Method setMethod;
0807:
0808:                ArrayPropertyGetSet(Method method, int index) {
0809:                    this .index = new Integer(index);
0810:                    getMethod = method;
0811:                }
0812:
0813:                private final static Method findSetter(Method getMethod,
0814:                        Class clz) {
0815:                    String name = getMethod.getName();
0816:                    name = "set" + name.substring(3);
0817:                    try {
0818:                        return clz.getMethod(name, new Class[] { int.class,
0819:                                getMethod.getReturnType() });
0820:                    } catch (Exception e) {
0821:                        log.debug("Cannot find setter method corresponding to "
0822:                                + getMethod, e);
0823:                    }
0824:                    return null;
0825:                }
0826:
0827:                /**
0828:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#getValue(java.lang.Object)
0829:                 */
0830:                public Object getValue(Object object) {
0831:                    Object ret = null;
0832:                    try {
0833:                        ret = getMethod.invoke(object, new Object[] { index });
0834:                    } catch (InvocationTargetException ex) {
0835:                        throw new WicketRuntimeException(
0836:                                "Error calling index property method: "
0837:                                        + getMethod + " on object: " + object,
0838:                                ex.getCause());
0839:                    } catch (Exception ex) {
0840:                        throw new WicketRuntimeException(
0841:                                "Error calling index property method: "
0842:                                        + getMethod + " on object: " + object,
0843:                                ex);
0844:                    }
0845:                    return ret;
0846:                }
0847:
0848:                /**
0849:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#setValue(java.lang.Object,
0850:                 *      java.lang.Object, org.apache.wicket.util.convert.IConverter)
0851:                 */
0852:                public void setValue(Object object, Object value,
0853:                        PropertyResolverConverter converter) {
0854:                    if (setMethod == null) {
0855:                        setMethod = findSetter(getMethod, object.getClass());
0856:                    }
0857:                    if (setMethod != null) {
0858:                        Object converted = converter.convert(value, getMethod
0859:                                .getReturnType());
0860:                        if (converted == null && value != null) {
0861:                            throw new ConversionException(
0862:                                    "Can't convert value: " + value
0863:                                            + " to class: "
0864:                                            + getMethod.getReturnType()
0865:                                            + " for setting it on " + object);
0866:                        }
0867:                        try {
0868:                            setMethod.invoke(object, new Object[] { index,
0869:                                    converted });
0870:                        } catch (InvocationTargetException ex) {
0871:                            throw new WicketRuntimeException(
0872:                                    "Error index property calling method: "
0873:                                            + setMethod + " on object: "
0874:                                            + object, ex.getCause());
0875:                        } catch (Exception ex) {
0876:                            throw new WicketRuntimeException(
0877:                                    "Error index property calling method: "
0878:                                            + setMethod + " on object: "
0879:                                            + object, ex);
0880:                        }
0881:                    } else {
0882:                        throw new WicketRuntimeException(
0883:                                "no set method defined for value: " + value
0884:                                        + " on object: " + object);
0885:                    }
0886:                }
0887:
0888:                /**
0889:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#getTargetClass()
0890:                 */
0891:                public Class getTargetClass() {
0892:                    return getMethod.getReturnType();
0893:                }
0894:
0895:                /**
0896:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#newValue(java.lang.Object)
0897:                 */
0898:                public Object newValue(Object object) {
0899:                    if (setMethod == null) {
0900:                        setMethod = findSetter(getMethod, object.getClass());
0901:                    }
0902:
0903:                    if (setMethod == null) {
0904:                        log.warn("Null setMethod");
0905:                        return null;
0906:                    }
0907:
0908:                    Class clz = getMethod.getReturnType();
0909:                    Object value = null;
0910:                    try {
0911:                        value = clz.newInstance();
0912:                        setMethod.invoke(object, new Object[] { index, value });
0913:                    } catch (Exception e) {
0914:                        log.warn("Cannot set new value " + value + " at index "
0915:                                + index, e);
0916:                    }
0917:                    return value;
0918:                }
0919:            }
0920:
0921:            private static final class MethodGetAndSet extends
0922:                    AbstractGetAndSet {
0923:                private final Method getMethod;
0924:                private final Method setMethod;
0925:                private final Field field;
0926:
0927:                MethodGetAndSet(Method getMethod, Method setMethod, Field field) {
0928:                    this .getMethod = getMethod;
0929:                    this .getMethod.setAccessible(true);
0930:                    this .field = field;
0931:                    this .setMethod = setMethod;
0932:                }
0933:
0934:                /**
0935:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#getValue(java.lang.Object)
0936:                 */
0937:                public final Object getValue(final Object object) {
0938:                    Object ret = null;
0939:                    try {
0940:                        ret = getMethod.invoke(object, null);
0941:                    } catch (InvocationTargetException ex) {
0942:                        throw new WicketRuntimeException(
0943:                                "Error calling method: " + getMethod
0944:                                        + " on object: " + object, ex
0945:                                        .getCause());
0946:                    } catch (Exception ex) {
0947:                        throw new WicketRuntimeException(
0948:                                "Error calling method: " + getMethod
0949:                                        + " on object: " + object, ex);
0950:                    }
0951:                    return ret;
0952:                }
0953:
0954:                /**
0955:                 * @param object
0956:                 * @param value
0957:                 * @param converter
0958:                 */
0959:                public final void setValue(final Object object,
0960:                        final Object value, PropertyResolverConverter converter) {
0961:                    if (setMethod != null) {
0962:                        Object converted = converter.convert(value, getMethod
0963:                                .getReturnType());
0964:                        if (converted == null) {
0965:                            if (value != null) {
0966:                                throw new ConversionException(
0967:                                        "Can't convert value: " + value
0968:                                                + " to class: "
0969:                                                + getMethod.getReturnType()
0970:                                                + " for setting it on "
0971:                                                + object);
0972:                            } else if (getMethod.getReturnType().isPrimitive()) {
0973:                                throw new ConversionException(
0974:                                        "Can't convert null value to a primitive class: "
0975:                                                + getMethod.getReturnType()
0976:                                                + " for setting it on "
0977:                                                + object);
0978:                            }
0979:                        }
0980:                        try {
0981:                            setMethod
0982:                                    .invoke(object, new Object[] { converted });
0983:                        } catch (InvocationTargetException ex) {
0984:                            throw new WicketRuntimeException(
0985:                                    "Error calling method: " + setMethod
0986:                                            + " on object: " + object, ex
0987:                                            .getCause());
0988:                        } catch (Exception ex) {
0989:                            throw new WicketRuntimeException(
0990:                                    "Error calling method: " + setMethod
0991:                                            + " on object: " + object, ex);
0992:                        }
0993:                    } else {
0994:                        throw new WicketRuntimeException(
0995:                                "no set method defined for value: " + value
0996:                                        + " on object: " + object);
0997:                    }
0998:                }
0999:
1000:                private final static Method findSetter(Method getMethod,
1001:                        Class clz) {
1002:                    String name = getMethod.getName();
1003:                    if (name.startsWith("get")) {
1004:                        name = "set" + name.substring(3);
1005:                    } else {
1006:                        name = "set" + name.substring(2);
1007:                    }
1008:                    try {
1009:                        Method method = clz.getMethod(name,
1010:                                new Class[] { getMethod.getReturnType() });
1011:                        if (method != null) {
1012:                            method.setAccessible(true);
1013:                        }
1014:                        return method;
1015:                    } catch (Exception e) {
1016:                        log.debug("Cannot find setter corresponding to "
1017:                                + getMethod, e);
1018:                    }
1019:                    return null;
1020:                }
1021:
1022:                /**
1023:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#newValue(java.lang.Object)
1024:                 */
1025:                public Object newValue(Object object) {
1026:                    if (setMethod == null) {
1027:                        log.warn("Null setMethod");
1028:                        return null;
1029:                    }
1030:
1031:                    Class clz = getMethod.getReturnType();
1032:                    Object value = null;
1033:                    try {
1034:                        value = clz.newInstance();
1035:                        setMethod.invoke(object, new Object[] { value });
1036:                    } catch (Exception e) {
1037:                        log.warn("Cannot set new value " + value, e);
1038:                    }
1039:                    return value;
1040:                }
1041:
1042:                /**
1043:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#getTargetClass()
1044:                 */
1045:                public Class getTargetClass() {
1046:                    return getMethod.getReturnType();
1047:                }
1048:
1049:                /**
1050:                 * @see org.apache.wicket.util.lang.PropertyResolver.AbstractGetAndSet#getGetter()
1051:                 */
1052:                public Method getGetter() {
1053:                    return getMethod;
1054:                }
1055:
1056:                /**
1057:                 * @see org.apache.wicket.util.lang.PropertyResolver.AbstractGetAndSet#getSetter()
1058:                 */
1059:                public Method getSetter() {
1060:                    return setMethod;
1061:                }
1062:
1063:                /**
1064:                 * @see org.apache.wicket.util.lang.PropertyResolver.AbstractGetAndSet#getField()
1065:                 */
1066:                public Field getField() {
1067:                    return field;
1068:                }
1069:            }
1070:
1071:            /**
1072:             * @author jcompagner
1073:             */
1074:            private static class FieldGetAndSetter extends AbstractGetAndSet {
1075:
1076:                private final Field field;
1077:
1078:                /**
1079:                 * Construct.
1080:                 * 
1081:                 * @param field
1082:                 */
1083:                public FieldGetAndSetter(Field field) {
1084:                    super ();
1085:                    this .field = field;
1086:                    this .field.setAccessible(true);
1087:                }
1088:
1089:                /**
1090:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#getValue(java.lang.Object)
1091:                 */
1092:                public Object getValue(Object object) {
1093:                    try {
1094:                        return field.get(object);
1095:                    } catch (Exception ex) {
1096:                        throw new WicketRuntimeException(
1097:                                "Error getting field value of field " + field
1098:                                        + " from object " + object, ex);
1099:                    }
1100:                }
1101:
1102:                /**
1103:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#newValue(java.lang.Object)
1104:                 */
1105:                public Object newValue(Object object) {
1106:                    Class clz = field.getType();
1107:                    Object value = null;
1108:                    try {
1109:                        value = clz.newInstance();
1110:                        field.set(object, value);
1111:                    } catch (Exception e) {
1112:                        log.warn("Cannot set field " + field + " to " + value,
1113:                                e);
1114:                    }
1115:                    return value;
1116:                }
1117:
1118:                /**
1119:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#setValue(java.lang.Object,
1120:                 *      java.lang.Object, org.apache.wicket.util.convert.IConverter)
1121:                 */
1122:                public void setValue(Object object, Object value,
1123:                        PropertyResolverConverter converter) {
1124:                    value = converter.convert(value, field.getType());
1125:                    try {
1126:                        field.set(object, value);
1127:                    } catch (Exception ex) {
1128:                        throw new WicketRuntimeException(
1129:                                "Error setting field value of field " + field
1130:                                        + " on object " + object + ", value "
1131:                                        + value, ex);
1132:                    }
1133:                }
1134:
1135:                /**
1136:                 * @see org.apache.wicket.util.lang.PropertyResolver.IGetAndSet#getTargetClass()
1137:                 */
1138:                public Class getTargetClass() {
1139:                    return field.getType();
1140:                }
1141:
1142:                public Field getField() {
1143:                    return field;
1144:                }
1145:            }
1146:
1147:            private static Map getClassesToGetAndSetters() {
1148:                Application app = Application.get();
1149:                Map result = (Map) applicationToClassesToGetAndSetters
1150:                        .get(Application.get());
1151:                if (result == null) {
1152:                    // Don't synchronize this - Doesn't matter if we create two of them,
1153:                    // as it's only a cache and the first will go out of scope and get
1154:                    // GC'ed.
1155:                    applicationToClassesToGetAndSetters.put(app,
1156:                            result = new ConcurrentHashMap(64));
1157:                }
1158:                return result;
1159:            }
1160:
1161:            /**
1162:             * Clean up cache for this app.
1163:             * 
1164:             * @param application
1165:             */
1166:            public static void destroy(Application application) {
1167:                applicationToClassesToGetAndSetters.remove(application);
1168:            }
1169:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.