Source Code Cross Referenced for OgnlRuntime.java in  » Scripting » OGNL » ognl » 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 » Scripting » OGNL » ognl 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        //--------------------------------------------------------------------------
0002:        //	Copyright (c) 1998-2004, Drew Davidson and Luke Blanshard
0003:        //  All rights reserved.
0004:        //
0005:        //  Redistribution and use in source and binary forms, with or without
0006:        //  modification, are permitted provided that the following conditions are
0007:        //  met:
0008:        //
0009:        //  Redistributions of source code must retain the above copyright notice,
0010:        //  this list of conditions and the following disclaimer.
0011:        //  Redistributions in binary form must reproduce the above copyright
0012:        //  notice, this list of conditions and the following disclaimer in the
0013:        //  documentation and/or other materials provided with the distribution.
0014:        //  Neither the name of the Drew Davidson nor the names of its contributors
0015:        //  may be used to endorse or promote products derived from this software
0016:        //  without specific prior written permission.
0017:        //
0018:        //  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0019:        //  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0020:        //  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
0021:        //  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
0022:        //  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
0023:        //  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
0024:        //  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
0025:        //  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
0026:        //  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0027:        //  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
0028:        //  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
0029:        //  DAMAGE.
0030:        //--------------------------------------------------------------------------
0031:        package ognl;
0032:
0033:        import java.beans.IndexedPropertyDescriptor;
0034:        import java.beans.IntrospectionException;
0035:        import java.beans.Introspector;
0036:        import java.beans.PropertyDescriptor;
0037:        import java.lang.reflect.AccessibleObject;
0038:        import java.lang.reflect.Constructor;
0039:        import java.lang.reflect.Field;
0040:        import java.lang.reflect.InvocationTargetException;
0041:        import java.lang.reflect.Member;
0042:        import java.lang.reflect.Method;
0043:        import java.lang.reflect.Modifier;
0044:        import java.lang.reflect.Proxy;
0045:        import java.math.BigDecimal;
0046:        import java.math.BigInteger;
0047:        import java.security.Permission;
0048:        import java.util.ArrayList;
0049:        import java.util.Arrays;
0050:        import java.util.Collection;
0051:        import java.util.Collections;
0052:        import java.util.Enumeration;
0053:        import java.util.HashMap;
0054:        import java.util.Iterator;
0055:        import java.util.List;
0056:        import java.util.Map;
0057:        import java.util.Set;
0058:
0059:        /**
0060:         * This is an abstract class with static methods that define runtime
0061:         * caching information in OGNL.
0062:         * @author Luke Blanshard (blanshlu@netscape.net)
0063:         * @author Drew Davidson (drew@ognl.org)
0064:         */
0065:        public abstract class OgnlRuntime extends Object {
0066:            public static final Object NotFound = new Object();
0067:            public static final List NotFoundList = new ArrayList();
0068:            public static final Map NotFoundMap = new HashMap();
0069:            public static final Object[] NoArguments = new Object[] {};
0070:            public static final Class[] NoArgumentTypes = new Class[] {};
0071:
0072:            /** Token returned by TypeConverter for no conversion possible */
0073:            public static final Object NoConversionPossible = "ognl.NoConversionPossible";
0074:
0075:            /** Not an indexed property */
0076:            public static int INDEXED_PROPERTY_NONE = 0;
0077:            /** JavaBeans IndexedProperty */
0078:            public static int INDEXED_PROPERTY_INT = 1;
0079:            /** OGNL ObjectIndexedProperty */
0080:            public static int INDEXED_PROPERTY_OBJECT = 2;
0081:
0082:            public static final String NULL_STRING = "" + null;
0083:
0084:            private static final String SET_PREFIX = "set";
0085:            private static final String GET_PREFIX = "get";
0086:            private static final String IS_PREFIX = "is";
0087:
0088:            /**
0089:                Prefix padding for hexadecimal numbers to HEX_LENGTH.
0090:             */
0091:            private static final Map HEX_PADDING = new HashMap();
0092:
0093:            /**
0094:                Hexadecimal prefix for printing "pointers".
0095:             */
0096:            private static final String HEX_PREFIX = "0x";
0097:
0098:            private static final int HEX_LENGTH = 8;
0099:            /**
0100:                Returned by <CODE>getUniqueDescriptor()</CODE> when the
0101:                object is <CODE>null</CODE>.
0102:             */
0103:            private static final String NULL_OBJECT_STRING = "<null>";
0104:
0105:            private static ClassCache methodAccessors = new ClassCache();
0106:            private static ClassCache propertyAccessors = new ClassCache();
0107:            private static ClassCache elementsAccessors = new ClassCache();
0108:            private static ClassCache nullHandlers = new ClassCache();
0109:            private static ClassCache propertyDescriptorCache = new ClassCache();
0110:            private static ClassCache constructorCache = new ClassCache();
0111:            private static ClassCache staticMethodCache = new ClassCache();
0112:            private static ClassCache instanceMethodCache = new ClassCache();
0113:            private static ClassCache invokePermissionCache = new ClassCache();
0114:            private static ClassCache fieldCache = new ClassCache();
0115:            private static List super classes = new ArrayList(); /* Used by fieldCache lookup */
0116:            private static ClassCache[] declaredMethods = new ClassCache[] {
0117:                    new ClassCache(), new ClassCache() }; /* set, get */
0118:            private static Map primitiveTypes = new HashMap(101);
0119:            private static ClassCache primitiveDefaults = new ClassCache();
0120:            private static Map methodParameterTypesCache = new HashMap(101);
0121:            private static Map ctorParameterTypesCache = new HashMap(101);
0122:            private static SecurityManager securityManager = System
0123:                    .getSecurityManager();
0124:            private static EvaluationPool evaluationPool = new EvaluationPool();
0125:            private static ObjectArrayPool objectArrayPool = new ObjectArrayPool();
0126:
0127:            /**
0128:                This is a highly specialized map for storing values keyed by Class objects.
0129:             */
0130:            private static class ClassCache extends Object {
0131:                /* this MUST be a power of 2 */
0132:                private static final int TABLE_SIZE = 512;
0133:
0134:                /* ...and now you see why.  The table size is used as a mask for generating hashes */
0135:                private static final int TABLE_SIZE_MASK = TABLE_SIZE - 1;
0136:
0137:                private Entry[] table;
0138:
0139:                private static class Entry extends Object {
0140:                    protected Entry next;
0141:                    protected Class key;
0142:                    protected Object value;
0143:
0144:                    public Entry(Class key, Object value) {
0145:                        super ();
0146:                        this .key = key;
0147:                        this .value = value;
0148:                    }
0149:                }
0150:
0151:                public ClassCache() {
0152:                    super ();
0153:                    this .table = new Entry[TABLE_SIZE];
0154:                }
0155:
0156:                public final Object get(Class key) {
0157:                    Object result = null;
0158:                    int i = key.hashCode() & TABLE_SIZE_MASK;
0159:
0160:                    for (Entry entry = table[i]; entry != null; entry = entry.next) {
0161:                        if (entry.key == key) {
0162:                            result = entry.value;
0163:                            break;
0164:                        }
0165:                    }
0166:                    return result;
0167:                }
0168:
0169:                public final Object put(Class key, Object value) {
0170:                    Object result = null;
0171:                    int i = key.hashCode() & TABLE_SIZE_MASK;
0172:                    Entry entry = table[i];
0173:
0174:                    if (entry == null) {
0175:                        table[i] = new Entry(key, value);
0176:                    } else {
0177:                        if (entry.key == key) {
0178:                            result = entry.value;
0179:                            entry.value = value;
0180:                        } else {
0181:                            while (true) {
0182:                                if (entry.key == key) {
0183:                                    /* replace value */
0184:                                    result = entry.value;
0185:                                    entry.value = value;
0186:                                    break;
0187:                                } else {
0188:                                    if (entry.next == null) {
0189:                                        /* add value */
0190:                                        entry.next = new Entry(key, value);
0191:                                        break;
0192:                                    }
0193:                                }
0194:                                entry = entry.next;
0195:                            }
0196:                        }
0197:                    }
0198:                    return result;
0199:                }
0200:            }
0201:
0202:            static {
0203:                PropertyAccessor p = new ArrayPropertyAccessor();
0204:                setPropertyAccessor(Object.class, new ObjectPropertyAccessor());
0205:                setPropertyAccessor(byte[].class, p);
0206:                setPropertyAccessor(short[].class, p);
0207:                setPropertyAccessor(char[].class, p);
0208:                setPropertyAccessor(int[].class, p);
0209:                setPropertyAccessor(long[].class, p);
0210:                setPropertyAccessor(float[].class, p);
0211:                setPropertyAccessor(double[].class, p);
0212:                setPropertyAccessor(Object[].class, p);
0213:                setPropertyAccessor(List.class, new ListPropertyAccessor());
0214:                setPropertyAccessor(Map.class, new MapPropertyAccessor());
0215:                setPropertyAccessor(Set.class, new SetPropertyAccessor());
0216:                setPropertyAccessor(Iterator.class,
0217:                        new IteratorPropertyAccessor());
0218:                setPropertyAccessor(Enumeration.class,
0219:                        new EnumerationPropertyAccessor());
0220:
0221:                ElementsAccessor e = new ArrayElementsAccessor();
0222:                setElementsAccessor(Object.class, new ObjectElementsAccessor());
0223:                setElementsAccessor(byte[].class, e);
0224:                setElementsAccessor(short[].class, e);
0225:                setElementsAccessor(char[].class, e);
0226:                setElementsAccessor(int[].class, e);
0227:                setElementsAccessor(long[].class, e);
0228:                setElementsAccessor(float[].class, e);
0229:                setElementsAccessor(double[].class, e);
0230:                setElementsAccessor(Object[].class, e);
0231:                setElementsAccessor(Collection.class,
0232:                        new CollectionElementsAccessor());
0233:                setElementsAccessor(Map.class, new MapElementsAccessor());
0234:                setElementsAccessor(Iterator.class,
0235:                        new IteratorElementsAccessor());
0236:                setElementsAccessor(Enumeration.class,
0237:                        new EnumerationElementsAccessor());
0238:                setElementsAccessor(Number.class, new NumberElementsAccessor());
0239:
0240:                NullHandler nh = new ObjectNullHandler();
0241:                setNullHandler(Object.class, nh);
0242:                setNullHandler(byte[].class, nh);
0243:                setNullHandler(short[].class, nh);
0244:                setNullHandler(char[].class, nh);
0245:                setNullHandler(int[].class, nh);
0246:                setNullHandler(long[].class, nh);
0247:                setNullHandler(float[].class, nh);
0248:                setNullHandler(double[].class, nh);
0249:                setNullHandler(Object[].class, nh);
0250:
0251:                MethodAccessor ma = new ObjectMethodAccessor();
0252:                setMethodAccessor(Object.class, ma);
0253:                setMethodAccessor(byte[].class, ma);
0254:                setMethodAccessor(short[].class, ma);
0255:                setMethodAccessor(char[].class, ma);
0256:                setMethodAccessor(int[].class, ma);
0257:                setMethodAccessor(long[].class, ma);
0258:                setMethodAccessor(float[].class, ma);
0259:                setMethodAccessor(double[].class, ma);
0260:                setMethodAccessor(Object[].class, ma);
0261:
0262:                primitiveTypes.put("boolean", Boolean.TYPE);
0263:                primitiveTypes.put("byte", Byte.TYPE);
0264:                primitiveTypes.put("short", Short.TYPE);
0265:                primitiveTypes.put("char", Character.TYPE);
0266:                primitiveTypes.put("int", Integer.TYPE);
0267:                primitiveTypes.put("long", Long.TYPE);
0268:                primitiveTypes.put("float", Float.TYPE);
0269:                primitiveTypes.put("double", Double.TYPE);
0270:
0271:                primitiveDefaults.put(Boolean.TYPE, Boolean.FALSE);
0272:                primitiveDefaults.put(Byte.TYPE, new Byte((byte) 0));
0273:                primitiveDefaults.put(Short.TYPE, new Short((short) 0));
0274:                primitiveDefaults.put(Character.TYPE, new Character((char) 0));
0275:                primitiveDefaults.put(Integer.TYPE, new Integer(0));
0276:                primitiveDefaults.put(Long.TYPE, new Long(0L));
0277:                primitiveDefaults.put(Float.TYPE, new Float(0.0f));
0278:                primitiveDefaults.put(Double.TYPE, new Double(0.0));
0279:                primitiveDefaults.put(BigInteger.class, new BigInteger("0"));
0280:                primitiveDefaults.put(BigDecimal.class, new BigDecimal(0.0));
0281:            }
0282:
0283:            /**
0284:                Gets the "target" class of an object for looking up accessors that
0285:                are registered on the target.  If the object is a Class object this
0286:                will return the Class itself, else it will return object's getClass()
0287:                result.
0288:             */
0289:            public static Class getTargetClass(Object o) {
0290:                return (o == null) ? null : ((o instanceof  Class) ? (Class) o
0291:                        : o.getClass());
0292:            }
0293:
0294:            /**
0295:                Returns the base name (the class name without the
0296:                package name prepended) of the object given.
0297:             */
0298:            public static String getBaseName(Object o) {
0299:                return (o == null) ? null : getClassBaseName(o.getClass());
0300:            }
0301:
0302:            /**
0303:                Returns the base name (the class name without the
0304:                package name prepended) of the class given.
0305:             */
0306:            public static String getClassBaseName(Class c) {
0307:                String s = c.getName();
0308:
0309:                return s.substring(s.lastIndexOf('.') + 1);
0310:            }
0311:
0312:            public static String getClassName(Object o, boolean fullyQualified) {
0313:                if (!(o instanceof  Class)) {
0314:                    o = o.getClass();
0315:                }
0316:                return getClassName((Class) o, fullyQualified);
0317:            }
0318:
0319:            public static String getClassName(Class c, boolean fullyQualified) {
0320:                return fullyQualified ? c.getName() : getClassBaseName(c);
0321:            }
0322:
0323:            /**
0324:                Returns the package name of the object's class.
0325:             */
0326:            public static String getPackageName(Object o) {
0327:                return (o == null) ? null : getClassPackageName(o.getClass());
0328:            }
0329:
0330:            /**
0331:                Returns the package name of the class given.
0332:             */
0333:            public static String getClassPackageName(Class c) {
0334:                String s = c.getName();
0335:                int i = s.lastIndexOf('.');
0336:
0337:                return (i < 0) ? null : s.substring(0, i);
0338:            }
0339:
0340:            /**
0341:                Returns a "pointer" string in the usual format for these
0342:                things - 0x<hex digits>.
0343:             */
0344:            public static String getPointerString(int num) {
0345:                StringBuffer result = new StringBuffer();
0346:                String hex = Integer.toHexString(num), pad;
0347:                Integer l = new Integer(hex.length());
0348:
0349:                //result.append(HEX_PREFIX);
0350:                if ((pad = (String) HEX_PADDING.get(l)) == null) {
0351:                    StringBuffer pb = new StringBuffer();
0352:
0353:                    for (int i = hex.length(); i < HEX_LENGTH; i++) {
0354:                        pb.append('0');
0355:                    }
0356:                    pad = new String(pb);
0357:                    HEX_PADDING.put(l, pad);
0358:                }
0359:                result.append(pad);
0360:                result.append(hex);
0361:                return new String(result);
0362:            }
0363:
0364:            /**
0365:                Returns a "pointer" string in the usual format for these
0366:                things - 0x<hex digits> for the object given.  This will
0367:                always return a unique value for each object.
0368:             */
0369:            public static String getPointerString(Object o) {
0370:                return getPointerString((o == null) ? 0 : System
0371:                        .identityHashCode(o));
0372:            }
0373:
0374:            /**
0375:                Returns a unique descriptor string that includes the object's
0376:                class and a unique integer identifier.  If fullyQualified is
0377:                true then the class name will be fully qualified to include
0378:                the package name, else it will be just the class' base name.
0379:             */
0380:            public static String getUniqueDescriptor(Object object,
0381:                    boolean fullyQualified) {
0382:                StringBuffer result = new StringBuffer();
0383:
0384:                if (object != null) {
0385:                    if (object instanceof  Proxy) {
0386:                        Class interfaceClass = object.getClass()
0387:                                .getInterfaces()[0];
0388:
0389:                        result.append(getClassName(interfaceClass,
0390:                                fullyQualified));
0391:                        result.append('^');
0392:                        object = Proxy.getInvocationHandler(object);
0393:                    }
0394:                    result.append(getClassName(object, fullyQualified));
0395:                    result.append('@');
0396:                    result.append(getPointerString(object));
0397:                } else {
0398:                    result.append(NULL_OBJECT_STRING);
0399:                }
0400:                return new String(result);
0401:            }
0402:
0403:            /**
0404:                Returns a unique descriptor string that includes the object's
0405:                class' base name and a unique integer identifier.
0406:             */
0407:            public static String getUniqueDescriptor(Object object) {
0408:                return getUniqueDescriptor(object, false);
0409:            }
0410:
0411:            /**
0412:                Utility to convert a List into an Object[] array.  If the list is zero
0413:                elements this will return a constant array; toArray() on List always
0414:                returns a new object and this is wasteful for our purposes.
0415:             */
0416:            public static Object[] toArray(List list) {
0417:                Object[] result;
0418:                int size = list.size();
0419:
0420:                if (size == 0) {
0421:                    result = NoArguments;
0422:                } else {
0423:                    result = getObjectArrayPool().create(list.size());
0424:                    for (int i = 0; i < size; i++) {
0425:                        result[i] = list.get(i);
0426:                    }
0427:                }
0428:                return result;
0429:            }
0430:
0431:            /**
0432:                Returns the parameter types of the given method.
0433:             */
0434:            public static Class[] getParameterTypes(Method m) {
0435:                synchronized (methodParameterTypesCache) {
0436:                    Class[] result;
0437:
0438:                    if ((result = (Class[]) methodParameterTypesCache.get(m)) == null) {
0439:                        methodParameterTypesCache.put(m, result = m
0440:                                .getParameterTypes());
0441:                    }
0442:                    return result;
0443:                }
0444:            }
0445:
0446:            /**
0447:                Returns the parameter types of the given method.
0448:             */
0449:            public static Class[] getParameterTypes(Constructor c) {
0450:                synchronized (ctorParameterTypesCache) {
0451:                    Class[] result;
0452:
0453:                    if ((result = (Class[]) ctorParameterTypesCache.get(c)) == null) {
0454:                        ctorParameterTypesCache.put(c, result = c
0455:                                .getParameterTypes());
0456:                    }
0457:                    return result;
0458:                }
0459:            }
0460:
0461:            /**
0462:             * Gets the SecurityManager that OGNL uses to determine permissions for
0463:             * invoking methods.
0464:             *
0465:             * @return SecurityManager for OGNL
0466:             */
0467:            public static SecurityManager getSecurityManager() {
0468:                return securityManager;
0469:            }
0470:
0471:            /**
0472:             * Sets the SecurityManager that OGNL uses to determine permissions for
0473:             * invoking methods.
0474:             *
0475:             * @param value SecurityManager to set
0476:             */
0477:            public static void setSecurityManager(SecurityManager value) {
0478:                securityManager = value;
0479:            }
0480:
0481:            /**
0482:                Permission will be named "invoke.<declaring-class>.<method-name>".
0483:             */
0484:            public static Permission getPermission(Method method) {
0485:                Permission result = null;
0486:                Class mc = method.getDeclaringClass();
0487:
0488:                synchronized (invokePermissionCache) {
0489:                    Map permissions = (Map) invokePermissionCache.get(mc);
0490:
0491:                    if (permissions == null) {
0492:                        invokePermissionCache.put(mc,
0493:                                permissions = new HashMap(101));
0494:                    }
0495:                    if ((result = (Permission) permissions
0496:                            .get(method.getName())) == null) {
0497:                        result = new OgnlInvokePermission("invoke."
0498:                                + mc.getName() + "." + method.getName());
0499:                        permissions.put(method.getName(), result);
0500:                    }
0501:                }
0502:                return result;
0503:            }
0504:
0505:            public static Object invokeMethod(Object target, Method method,
0506:                    Object[] argsArray) throws InvocationTargetException,
0507:                    IllegalAccessException {
0508:                Object result;
0509:                boolean wasAccessible = true;
0510:
0511:                if (securityManager != null) {
0512:                    try {
0513:                        securityManager.checkPermission(getPermission(method));
0514:                    } catch (SecurityException ex) {
0515:                        throw new IllegalAccessException("Method [" + method
0516:                                + "] cannot be accessed.");
0517:                    }
0518:                }
0519:                if (!Modifier.isPublic(method.getModifiers())
0520:                        || !Modifier.isPublic(method.getDeclaringClass()
0521:                                .getModifiers())) {
0522:                    if (!(wasAccessible = ((AccessibleObject) method)
0523:                            .isAccessible())) {
0524:                        ((AccessibleObject) method).setAccessible(true);
0525:                    }
0526:                }
0527:                result = method.invoke(target, argsArray);
0528:                if (!wasAccessible) {
0529:                    ((AccessibleObject) method).setAccessible(false);
0530:                }
0531:                return result;
0532:            }
0533:
0534:            /**
0535:             * Gets the class for a method argument that is appropriate for looking up methods
0536:             * by reflection, by looking for the standard primitive wrapper classes and
0537:             * exchanging for them their underlying primitive class objects.  Other classes are
0538:             * passed through unchanged.
0539:             *
0540:             * @param arg an object that is being passed to a method
0541:             * @return the class to use to look up the method
0542:             */
0543:            public static final Class getArgClass(Object arg) {
0544:                if (arg == null)
0545:                    return null;
0546:                Class c = arg.getClass();
0547:                if (c == Boolean.class)
0548:                    return Boolean.TYPE;
0549:                else if (c.getSuperclass() == Number.class) {
0550:                    if (c == Integer.class)
0551:                        return Integer.TYPE;
0552:                    if (c == Double.class)
0553:                        return Double.TYPE;
0554:                    if (c == Byte.class)
0555:                        return Byte.TYPE;
0556:                    if (c == Long.class)
0557:                        return Long.TYPE;
0558:                    if (c == Float.class)
0559:                        return Float.TYPE;
0560:                    if (c == Short.class)
0561:                        return Short.TYPE;
0562:                } else if (c == Character.class)
0563:                    return Character.TYPE;
0564:                return c;
0565:            }
0566:
0567:            /**
0568:             * Tells whether the given object is compatible with the given class
0569:             * ---that is, whether the given object can be passed as an argument
0570:             * to a method or constructor whose parameter type is the given class.
0571:             * If object is null this will return true because null is compatible
0572:             * with any type.
0573:             */
0574:            public static final boolean isTypeCompatible(Object object, Class c) {
0575:                boolean result = true;
0576:
0577:                if (object != null) {
0578:                    if (c.isPrimitive()) {
0579:                        if (getArgClass(object) != c) {
0580:                            result = false;
0581:                        }
0582:                    } else if (!c.isInstance(object)) {
0583:                        result = false;
0584:                    }
0585:                }
0586:                return result;
0587:            }
0588:
0589:            /**
0590:             * Tells whether the given array of objects is compatible with the given array of
0591:             * classes---that is, whether the given array of objects can be passed as arguments
0592:             * to a method or constructor whose parameter types are the given array of classes.
0593:             */
0594:            public static final boolean areArgsCompatible(Object[] args,
0595:                    Class[] classes) {
0596:                boolean result = true;
0597:
0598:                if (args.length != classes.length) {
0599:                    result = false;
0600:                } else {
0601:                    for (int index = 0, count = args.length; result
0602:                            && (index < count); ++index) {
0603:                        result = isTypeCompatible(args[index], classes[index]);
0604:                    }
0605:                }
0606:                return result;
0607:            }
0608:
0609:            /**
0610:             * Tells whether the first array of classes is more specific than the second.
0611:             * Assumes that the two arrays are of the same length.
0612:             */
0613:            public static final boolean isMoreSpecific(Class[] classes1,
0614:                    Class[] classes2) {
0615:                for (int index = 0, count = classes1.length; index < count; ++index) {
0616:                    Class c1 = classes1[index], c2 = classes2[index];
0617:                    if (c1 == c2)
0618:                        continue;
0619:                    else if (c1.isPrimitive())
0620:                        return true;
0621:                    else if (c1.isAssignableFrom(c2))
0622:                        return false;
0623:                    else if (c2.isAssignableFrom(c1))
0624:                        return true;
0625:                }
0626:
0627:                // They are the same!  So the first is not more specific than the second.
0628:                return false;
0629:            }
0630:
0631:            public static final String getModifierString(int modifiers) {
0632:                String result;
0633:
0634:                if (Modifier.isPublic(modifiers))
0635:                    result = "public";
0636:                else if (Modifier.isProtected(modifiers))
0637:                    result = "protected";
0638:                else if (Modifier.isPrivate(modifiers))
0639:                    result = "private";
0640:                else
0641:                    result = "";
0642:                if (Modifier.isStatic(modifiers))
0643:                    result = "static " + result;
0644:                if (Modifier.isFinal(modifiers))
0645:                    result = "final " + result;
0646:                if (Modifier.isNative(modifiers))
0647:                    result = "native " + result;
0648:                if (Modifier.isSynchronized(modifiers))
0649:                    result = "synchronized " + result;
0650:                if (Modifier.isTransient(modifiers))
0651:                    result = "transient " + result;
0652:                return result;
0653:            }
0654:
0655:            public static final Class classForName(OgnlContext context,
0656:                    String className) throws ClassNotFoundException {
0657:                Class result = (Class) primitiveTypes.get(className);
0658:
0659:                if (result == null) {
0660:                    ClassResolver resolver;
0661:
0662:                    if ((context == null)
0663:                            || ((resolver = context.getClassResolver()) == null)) {
0664:                        resolver = OgnlContext.DEFAULT_CLASS_RESOLVER;
0665:                    }
0666:                    result = resolver.classForName(className, context);
0667:                }
0668:                return result;
0669:            }
0670:
0671:            public static final boolean isInstance(OgnlContext context,
0672:                    Object value, String className) throws OgnlException {
0673:                try {
0674:                    Class c = classForName(context, className);
0675:                    return c.isInstance(value);
0676:                } catch (ClassNotFoundException e) {
0677:                    throw new OgnlException("No such class: " + className, e);
0678:                }
0679:            }
0680:
0681:            public static Object getPrimitiveDefaultValue(Class forClass) {
0682:                return primitiveDefaults.get(forClass);
0683:            }
0684:
0685:            public static Object getConvertedType(OgnlContext context,
0686:                    Object target, Member member, String propertyName,
0687:                    Object value, Class type) {
0688:                return context.getTypeConverter().convertValue(context, target,
0689:                        member, propertyName, value, type);
0690:            }
0691:
0692:            public static boolean getConvertedTypes(OgnlContext context,
0693:                    Object target, Member member, String propertyName,
0694:                    Class[] parameterTypes, Object[] args, Object[] newArgs) {
0695:                boolean result = false;
0696:
0697:                if (parameterTypes.length == args.length) {
0698:                    result = true;
0699:                    for (int i = 0, ilast = parameterTypes.length - 1; result
0700:                            && (i <= ilast); i++) {
0701:                        Object arg = args[i];
0702:                        Class type = parameterTypes[i];
0703:
0704:                        if (isTypeCompatible(arg, type)) {
0705:                            newArgs[i] = arg;
0706:                        } else {
0707:                            Object v = getConvertedType(context, target,
0708:                                    member, propertyName, arg, type);
0709:
0710:                            if (v == OgnlRuntime.NoConversionPossible) {
0711:                                result = false;
0712:                            } else {
0713:                                newArgs[i] = v;
0714:                            }
0715:                        }
0716:                    }
0717:                }
0718:                return result;
0719:            }
0720:
0721:            public static Method getConvertedMethodAndArgs(OgnlContext context,
0722:                    Object target, String propertyName, List methods,
0723:                    Object[] args, Object[] newArgs) {
0724:                Method result = null;
0725:                TypeConverter converter = context.getTypeConverter();
0726:
0727:                if ((converter != null) && (methods != null)) {
0728:                    for (int i = 0, icount = methods.size(); (result == null)
0729:                            && (i < icount); i++) {
0730:                        Method m = (Method) methods.get(i);
0731:                        Class[] parameterTypes = getParameterTypes(m);
0732:
0733:                        if (getConvertedTypes(context, target, m, propertyName,
0734:                                parameterTypes, args, newArgs)) {
0735:                            result = m;
0736:                        }
0737:                    }
0738:                }
0739:                return result;
0740:            }
0741:
0742:            public static Constructor getConvertedConstructorAndArgs(
0743:                    OgnlContext context, Object target, List constructors,
0744:                    Object[] args, Object[] newArgs) {
0745:                Constructor result = null;
0746:                TypeConverter converter = context.getTypeConverter();
0747:
0748:                if ((converter != null) && (constructors != null)) {
0749:                    for (int i = 0, icount = constructors.size(); (result == null)
0750:                            && (i < icount); i++) {
0751:                        Constructor ctor = (Constructor) constructors.get(i);
0752:                        Class[] parameterTypes = getParameterTypes(ctor);
0753:
0754:                        if (getConvertedTypes(context, target, ctor, null,
0755:                                parameterTypes, args, newArgs)) {
0756:                            result = ctor;
0757:                        }
0758:                    }
0759:                }
0760:                return result;
0761:            }
0762:
0763:            /**
0764:                Gets the appropriate method to be called for the given target, method name and arguments.
0765:                If successful this method will return the Method within the target that can be called
0766:                and the converted arguments in actualArgs.  If unsuccessful this method will return
0767:                null and the actualArgs will be empty.
0768:             */
0769:            public static Method getAppropriateMethod(OgnlContext context,
0770:                    Object source, Object target, String methodName,
0771:                    String propertyName, List methods, Object[] args,
0772:                    Object[] actualArgs) {
0773:                Method result = null;
0774:                Class[] resultParameterTypes = null;
0775:
0776:                if (methods != null) {
0777:                    for (int i = 0, icount = methods.size(); i < icount; i++) {
0778:                        Method m = (Method) methods.get(i);
0779:                        Class[] mParameterTypes = getParameterTypes(m);
0780:
0781:                        if (areArgsCompatible(args, mParameterTypes)
0782:                                && ((result == null) || isMoreSpecific(
0783:                                        mParameterTypes, resultParameterTypes))) {
0784:                            result = m;
0785:                            resultParameterTypes = mParameterTypes;
0786:                            System.arraycopy(args, 0, actualArgs, 0,
0787:                                    args.length);
0788:                            for (int j = 0; j < mParameterTypes.length; j++) {
0789:                                Class type = mParameterTypes[j];
0790:
0791:                                if (type.isPrimitive()
0792:                                        && (actualArgs[j] == null)) {
0793:                                    actualArgs[j] = getConvertedType(context,
0794:                                            source, result, propertyName, null,
0795:                                            type);
0796:                                }
0797:                            }
0798:                        }
0799:                    }
0800:                }
0801:                if (result == null) {
0802:                    result = getConvertedMethodAndArgs(context, target,
0803:                            propertyName, methods, args, actualArgs);
0804:                }
0805:                return result;
0806:            }
0807:
0808:            public static Object callAppropriateMethod(OgnlContext context,
0809:                    Object source, Object target, String methodName,
0810:                    String propertyName, List methods, Object[] args)
0811:                    throws MethodFailedException {
0812:                Throwable reason = null;
0813:                Object[] actualArgs = objectArrayPool.create(args.length);
0814:
0815:                try {
0816:                    Method method = getAppropriateMethod(context, source,
0817:                            target, methodName, propertyName, methods, args,
0818:                            actualArgs);
0819:
0820:                    if ((method == null)
0821:                            || !isMethodAccessible(context, source, method,
0822:                                    propertyName)) {
0823:                        StringBuffer buffer = new StringBuffer();
0824:
0825:                        if (args != null) {
0826:                            for (int i = 0, ilast = args.length - 1; i <= ilast; i++) {
0827:                                Object arg = args[i];
0828:
0829:                                buffer.append((arg == null) ? NULL_STRING : arg
0830:                                        .getClass().getName());
0831:                                if (i < ilast) {
0832:                                    buffer.append(", ");
0833:                                }
0834:                            }
0835:                        }
0836:                        throw new NoSuchMethodException(methodName + "("
0837:                                + buffer + ")");
0838:                    }
0839:                    return invokeMethod(target, method, actualArgs);
0840:                } catch (NoSuchMethodException e) {
0841:                    reason = e;
0842:                } catch (IllegalAccessException e) {
0843:                    reason = e;
0844:                } catch (InvocationTargetException e) {
0845:                    reason = e.getTargetException();
0846:                } finally {
0847:                    objectArrayPool.recycle(actualArgs);
0848:                }
0849:                throw new MethodFailedException(source, methodName, reason);
0850:            }
0851:
0852:            public static final Object callStaticMethod(OgnlContext context,
0853:                    String className, String methodName, Object[] args)
0854:                    throws OgnlException, MethodFailedException {
0855:                try {
0856:                    Object result;
0857:                    Class targetClass = classForName(context, className);
0858:                    MethodAccessor ma = getMethodAccessor(targetClass);
0859:
0860:                    return ma.callStaticMethod(context, targetClass,
0861:                            methodName, args);
0862:                } catch (ClassNotFoundException ex) {
0863:                    throw new MethodFailedException(className, methodName, ex);
0864:                }
0865:            }
0866:
0867:            public static final Object callMethod(OgnlContext context,
0868:                    Object target, String methodName, String propertyName,
0869:                    Object[] args) throws OgnlException, MethodFailedException {
0870:                Object result;
0871:
0872:                if (target != null) {
0873:                    MethodAccessor ma = getMethodAccessor(target.getClass());
0874:
0875:                    result = ma.callMethod(context, target, methodName, args);
0876:                } else {
0877:                    throw new NullPointerException("target is null for method "
0878:                            + methodName);
0879:                }
0880:                return result;
0881:            }
0882:
0883:            public static final Object callConstructor(OgnlContext context,
0884:                    String className, Object[] args) throws OgnlException {
0885:                Throwable reason = null;
0886:                Object[] actualArgs = args;
0887:
0888:                try {
0889:                    Constructor ctor = null;
0890:                    Class[] ctorParameterTypes = null;
0891:                    Class target = classForName(context, className);
0892:                    List constructors = getConstructors(target);
0893:
0894:                    for (int i = 0, icount = constructors.size(); i < icount; i++) {
0895:                        Constructor c = (Constructor) constructors.get(i);
0896:                        Class[] cParameterTypes = getParameterTypes(c);
0897:
0898:                        if (areArgsCompatible(args, cParameterTypes)
0899:                                && (ctor == null || isMoreSpecific(
0900:                                        cParameterTypes, ctorParameterTypes))) {
0901:                            ctor = c;
0902:                            ctorParameterTypes = cParameterTypes;
0903:                        }
0904:                    }
0905:                    if (ctor == null) {
0906:                        actualArgs = objectArrayPool.create(args.length);
0907:                        if ((ctor = getConvertedConstructorAndArgs(context,
0908:                                target, constructors, args, actualArgs)) == null) {
0909:                            throw new NoSuchMethodException();
0910:                        }
0911:                    }
0912:                    if (!context.getMemberAccess().isAccessible(context,
0913:                            target, ctor, null)) {
0914:                        throw new IllegalAccessException("access denied to "
0915:                                + target.getName() + "()");
0916:                    }
0917:                    return ctor.newInstance(actualArgs);
0918:                } catch (ClassNotFoundException e) {
0919:                    reason = e;
0920:                } catch (NoSuchMethodException e) {
0921:                    reason = e;
0922:                } catch (IllegalAccessException e) {
0923:                    reason = e;
0924:                } catch (InvocationTargetException e) {
0925:                    reason = e.getTargetException();
0926:                } catch (InstantiationException e) {
0927:                    reason = e;
0928:                } finally {
0929:                    if (actualArgs != args) {
0930:                        objectArrayPool.recycle(actualArgs);
0931:                    }
0932:                }
0933:
0934:                throw new MethodFailedException(className, "new", reason);
0935:            }
0936:
0937:            public static final Object getMethodValue(OgnlContext context,
0938:                    Object target, String propertyName) throws OgnlException,
0939:                    IllegalAccessException, NoSuchMethodException,
0940:                    IntrospectionException {
0941:                return getMethodValue(context, target, propertyName, false);
0942:            }
0943:
0944:            /**
0945:                If the checkAccessAndExistence flag is true this method will check to see if the
0946:                method exists and if it is accessible according to the context's MemberAccess.
0947:                If neither test passes this will return NotFound.
0948:             */
0949:            public static final Object getMethodValue(OgnlContext context,
0950:                    Object target, String propertyName,
0951:                    boolean checkAccessAndExistence) throws OgnlException,
0952:                    IllegalAccessException, NoSuchMethodException,
0953:                    IntrospectionException {
0954:                Object result = null;
0955:                Method m = getGetMethod(context, (target == null) ? null
0956:                        : target.getClass(), propertyName);
0957:
0958:                if (checkAccessAndExistence) {
0959:                    if ((m == null)
0960:                            || !context.getMemberAccess().isAccessible(context,
0961:                                    target, m, propertyName)) {
0962:                        result = NotFound;
0963:                    }
0964:                }
0965:                if (result == null) {
0966:                    if (m != null) {
0967:                        try {
0968:                            result = invokeMethod(target, m, NoArguments);
0969:                        } catch (InvocationTargetException ex) {
0970:                            throw new OgnlException(propertyName, ex
0971:                                    .getTargetException());
0972:                        }
0973:                    } else {
0974:                        throw new NoSuchMethodException(propertyName);
0975:                    }
0976:                }
0977:                return result;
0978:            }
0979:
0980:            public static final boolean setMethodValue(OgnlContext context,
0981:                    Object target, String propertyName, Object value)
0982:                    throws OgnlException, IllegalAccessException,
0983:                    NoSuchMethodException, MethodFailedException,
0984:                    IntrospectionException {
0985:                return setMethodValue(context, target, propertyName, value,
0986:                        false);
0987:            }
0988:
0989:            public static final boolean setMethodValue(OgnlContext context,
0990:                    Object target, String propertyName, Object value,
0991:                    boolean checkAccessAndExistence) throws OgnlException,
0992:                    IllegalAccessException, NoSuchMethodException,
0993:                    MethodFailedException, IntrospectionException {
0994:                boolean result = true;
0995:                Method m = getSetMethod(context, (target == null) ? null
0996:                        : target.getClass(), propertyName);
0997:
0998:                if (checkAccessAndExistence) {
0999:                    if ((m == null)
1000:                            || !context.getMemberAccess().isAccessible(context,
1001:                                    target, m, propertyName)) {
1002:                        result = false;
1003:                    }
1004:                }
1005:                if (result) {
1006:                    if (m != null) {
1007:                        Object[] args = objectArrayPool.create(value);
1008:
1009:                        try {
1010:                            callAppropriateMethod(context, target, target, m
1011:                                    .getName(), propertyName, Collections
1012:                                    .nCopies(1, m), args);
1013:                        } finally {
1014:                            objectArrayPool.recycle(args);
1015:                        }
1016:                    } else {
1017:                        result = false;
1018:                    }
1019:                }
1020:                return result;
1021:            }
1022:
1023:            public static final List getConstructors(Class targetClass) {
1024:                List result;
1025:
1026:                synchronized (constructorCache) {
1027:                    if ((result = (List) constructorCache.get(targetClass)) == null) {
1028:                        constructorCache.put(targetClass, result = Arrays
1029:                                .asList(targetClass.getConstructors()));
1030:                    }
1031:                }
1032:                return result;
1033:            }
1034:
1035:            public static final Map getMethods(Class targetClass,
1036:                    boolean staticMethods) {
1037:                ClassCache cache = (staticMethods ? staticMethodCache
1038:                        : instanceMethodCache);
1039:                Map result;
1040:
1041:                synchronized (cache) {
1042:                    if ((result = (Map) cache.get(targetClass)) == null) {
1043:                        cache.put(targetClass, result = new HashMap(23));
1044:                        for (Class c = targetClass; c != null; c = c
1045:                                .getSuperclass()) {
1046:                            Method[] ma = c.getDeclaredMethods();
1047:
1048:                            for (int i = 0, icount = ma.length; i < icount; i++) {
1049:                                if (Modifier.isStatic(ma[i].getModifiers()) == staticMethods) {
1050:                                    List ml = (List) result
1051:                                            .get(ma[i].getName());
1052:
1053:                                    if (ml == null)
1054:                                        result.put(ma[i].getName(),
1055:                                                ml = new ArrayList());
1056:                                    ml.add(ma[i]);
1057:                                }
1058:                            }
1059:                        }
1060:                    }
1061:                }
1062:                return result;
1063:            }
1064:
1065:            public static final List getMethods(Class targetClass, String name,
1066:                    boolean staticMethods) {
1067:                return (List) getMethods(targetClass, staticMethods).get(name);
1068:            }
1069:
1070:            public static final Map getFields(Class targetClass) {
1071:                Map result;
1072:
1073:                synchronized (fieldCache) {
1074:                    if ((result = (Map) fieldCache.get(targetClass)) == null) {
1075:                        Field fa[];
1076:
1077:                        result = new HashMap(23);
1078:                        fa = targetClass.getDeclaredFields();
1079:                        for (int i = 0; i < fa.length; i++) {
1080:                            result.put(fa[i].getName(), fa[i]);
1081:                        }
1082:                        fieldCache.put(targetClass, result);
1083:                    }
1084:                }
1085:                return result;
1086:            }
1087:
1088:            public static final Field getField(Class inClass, String name) {
1089:                Field result = null;
1090:
1091:                synchronized (fieldCache) {
1092:                    Object o = getFields(inClass).get(name);
1093:
1094:                    if (o == null) {
1095:                        super classes.clear();
1096:                        for (Class sc = inClass; (sc != null)
1097:                                && (result == null); sc = sc.getSuperclass()) {
1098:                            if ((o = getFields(sc).get(name)) == NotFound)
1099:                                break;
1100:                            super classes.add(sc);
1101:                            if ((result = (Field) o) != null)
1102:                                break;
1103:                        }
1104:                        /*
1105:                            Bubble the found value (either cache miss or actual field)
1106:                            to all supeclasses that we saw for quicker access next time.
1107:                         */
1108:                        for (int i = 0, icount = super classes.size(); i < icount; i++) {
1109:                            getFields((Class) super classes.get(i)).put(name,
1110:                                    (result == null) ? NotFound : result);
1111:                        }
1112:                    } else {
1113:                        if (o instanceof  Field) {
1114:                            result = (Field) o;
1115:                        } else {
1116:                            if (result == NotFound)
1117:                                result = null;
1118:                        }
1119:                    }
1120:                }
1121:                return result;
1122:            }
1123:
1124:            public static final Object getFieldValue(OgnlContext context,
1125:                    Object target, String propertyName)
1126:                    throws NoSuchFieldException {
1127:                return getFieldValue(context, target, propertyName, false);
1128:            }
1129:
1130:            public static final Object getFieldValue(OgnlContext context,
1131:                    Object target, String propertyName,
1132:                    boolean checkAccessAndExistence)
1133:                    throws NoSuchFieldException {
1134:                Object result = null;
1135:                Field f = getField((target == null) ? null : target.getClass(),
1136:                        propertyName);
1137:
1138:                if (checkAccessAndExistence) {
1139:                    if ((f == null)
1140:                            || !context.getMemberAccess().isAccessible(context,
1141:                                    target, f, propertyName)) {
1142:                        result = NotFound;
1143:                    }
1144:                }
1145:                if (result == null) {
1146:                    if (f == null) {
1147:                        throw new NoSuchFieldException(propertyName);
1148:                    } else {
1149:                        try {
1150:                            Object state = null;
1151:
1152:                            if ((f != null)
1153:                                    && !Modifier.isStatic(f.getModifiers())) {
1154:                                state = context.getMemberAccess().setup(
1155:                                        context, target, f, propertyName);
1156:                                result = f.get(target);
1157:                                context.getMemberAccess().restore(context,
1158:                                        target, f, propertyName, state);
1159:                            } else
1160:                                throw new NoSuchFieldException(propertyName);
1161:                        } catch (IllegalAccessException ex) {
1162:                            throw new NoSuchFieldException(propertyName);
1163:                        }
1164:                    }
1165:                }
1166:                return result;
1167:            }
1168:
1169:            public static final boolean setFieldValue(OgnlContext context,
1170:                    Object target, String propertyName, Object value)
1171:                    throws OgnlException {
1172:                boolean result = false;
1173:
1174:                try {
1175:                    Field f = getField((target == null) ? null : target
1176:                            .getClass(), propertyName);
1177:                    Object state;
1178:
1179:                    if ((f != null) && !Modifier.isStatic(f.getModifiers())) {
1180:                        state = context.getMemberAccess().setup(context,
1181:                                target, f, propertyName);
1182:                        try {
1183:                            if (isTypeCompatible(value, f.getType())
1184:                                    || ((value = getConvertedType(context,
1185:                                            target, f, propertyName, value, f
1186:                                                    .getType())) != null)) {
1187:                                f.set(target, value);
1188:                                result = true;
1189:                            }
1190:                        } finally {
1191:                            context.getMemberAccess().restore(context, target,
1192:                                    f, propertyName, state);
1193:                        }
1194:                    }
1195:                } catch (IllegalAccessException ex) {
1196:                    throw new NoSuchPropertyException(target, propertyName, ex);
1197:                }
1198:                return result;
1199:            }
1200:
1201:            public static final boolean isFieldAccessible(OgnlContext context,
1202:                    Object target, Class inClass, String propertyName) {
1203:                return isFieldAccessible(context, target, getField(inClass,
1204:                        propertyName), propertyName);
1205:            }
1206:
1207:            public static final boolean isFieldAccessible(OgnlContext context,
1208:                    Object target, Field field, String propertyName) {
1209:                return context.getMemberAccess().isAccessible(context, target,
1210:                        field, propertyName);
1211:            }
1212:
1213:            public static final boolean hasField(OgnlContext context,
1214:                    Object target, Class inClass, String propertyName) {
1215:                Field f = getField(inClass, propertyName);
1216:
1217:                return (f != null)
1218:                        && isFieldAccessible(context, target, f, propertyName);
1219:            }
1220:
1221:            public static final Object getStaticField(OgnlContext context,
1222:                    String className, String fieldName) throws OgnlException {
1223:                Exception reason = null;
1224:                try {
1225:                    Class c = classForName(context, className);
1226:
1227:                    /*
1228:                        Check for virtual static field "class"; this cannot interfere with
1229:                        normal static fields because it is a reserved word.
1230:                     */
1231:                    if (fieldName.equals("class")) {
1232:                        return c;
1233:                    } else {
1234:                        Field f = c.getField(fieldName);
1235:                        if (!Modifier.isStatic(f.getModifiers()))
1236:                            throw new OgnlException("Field " + fieldName
1237:                                    + " of class " + className
1238:                                    + " is not static");
1239:                        return f.get(null);
1240:                    }
1241:                } catch (ClassNotFoundException e) {
1242:                    reason = e;
1243:                } catch (NoSuchFieldException e) {
1244:                    reason = e;
1245:                } catch (SecurityException e) {
1246:                    reason = e;
1247:                } catch (IllegalAccessException e) {
1248:                    reason = e;
1249:                }
1250:
1251:                throw new OgnlException("Could not get static field "
1252:                        + fieldName + " from class " + className, reason);
1253:            }
1254:
1255:            public static final List getDeclaredMethods(Class targetClass,
1256:                    String propertyName, boolean findSets) {
1257:                List result = null;
1258:                ClassCache cache = declaredMethods[findSets ? 0 : 1];
1259:
1260:                synchronized (cache) {
1261:                    Map propertyCache = (Map) cache.get(targetClass);
1262:
1263:                    if ((propertyCache == null)
1264:                            || ((result = (List) propertyCache
1265:                                    .get(propertyName)) == null)) {
1266:                        String baseName = Character.toUpperCase(propertyName
1267:                                .charAt(0))
1268:                                + propertyName.substring(1);
1269:                        int len = baseName.length();
1270:
1271:                        for (Class c = targetClass; c != null; c = c
1272:                                .getSuperclass()) {
1273:                            Method[] methods = c.getDeclaredMethods();
1274:
1275:                            for (int i = 0; i < methods.length; i++) {
1276:                                String ms = methods[i].getName();
1277:
1278:                                if (ms.endsWith(baseName)) {
1279:                                    boolean isSet = false, isGet = false, isIs = false;
1280:
1281:                                    if ((isSet = ms.startsWith(SET_PREFIX))
1282:                                            || (isGet = ms
1283:                                                    .startsWith(GET_PREFIX))
1284:                                            || (isIs = ms.startsWith(IS_PREFIX))) {
1285:                                        int prefixLength = (isIs ? 2 : 3);
1286:
1287:                                        if (isSet == findSets) {
1288:                                            if (baseName.length() == (ms
1289:                                                    .length() - prefixLength)) {
1290:                                                if (result == null) {
1291:                                                    result = new ArrayList();
1292:                                                }
1293:                                                result.add(methods[i]);
1294:                                            }
1295:                                        }
1296:                                    }
1297:                                }
1298:                            }
1299:                        }
1300:                        if (propertyCache == null) {
1301:                            cache.put(targetClass, propertyCache = new HashMap(
1302:                                    101));
1303:                        }
1304:                        propertyCache.put(propertyName,
1305:                                (result == null) ? NotFoundList : result);
1306:                    }
1307:                    return (result == NotFoundList) ? null : result;
1308:                }
1309:            }
1310:
1311:            public static final Method getGetMethod(OgnlContext context,
1312:                    Class targetClass, String propertyName)
1313:                    throws IntrospectionException, OgnlException {
1314:                Method result = null;
1315:                PropertyDescriptor pd = getPropertyDescriptor(targetClass,
1316:                        propertyName);
1317:
1318:                if (pd == null) {
1319:                    List methods = getDeclaredMethods(targetClass,
1320:                            propertyName, false /* find 'get' methods */);
1321:
1322:                    if (methods != null) {
1323:                        for (int i = 0, icount = methods.size(); i < icount; i++) {
1324:                            Method m = (Method) methods.get(i);
1325:                            Class[] mParameterTypes = getParameterTypes(m);
1326:
1327:                            if (mParameterTypes.length == 0) {
1328:                                result = m;
1329:                                break;
1330:                            }
1331:                        }
1332:                    }
1333:                } else {
1334:                    result = pd.getReadMethod();
1335:                }
1336:                return result;
1337:            }
1338:
1339:            public static final boolean isMethodAccessible(OgnlContext context,
1340:                    Object target, Method method, String propertyName) {
1341:                return (method == null) ? false : context.getMemberAccess()
1342:                        .isAccessible(context, target, method, propertyName);
1343:            }
1344:
1345:            public static final boolean hasGetMethod(OgnlContext context,
1346:                    Object target, Class targetClass, String propertyName)
1347:                    throws IntrospectionException, OgnlException {
1348:                return isMethodAccessible(context, target, getGetMethod(
1349:                        context, targetClass, propertyName), propertyName);
1350:            }
1351:
1352:            public static final Method getSetMethod(OgnlContext context,
1353:                    Class targetClass, String propertyName)
1354:                    throws IntrospectionException, OgnlException {
1355:                Method result = null;
1356:                PropertyDescriptor pd = getPropertyDescriptor(targetClass,
1357:                        propertyName);
1358:
1359:                if (pd == null) {
1360:                    List methods = getDeclaredMethods(targetClass,
1361:                            propertyName, true /* find 'set' methods */);
1362:
1363:                    if (methods != null) {
1364:                        for (int i = 0, icount = methods.size(); i < icount; i++) {
1365:                            Method m = (Method) methods.get(i);
1366:                            Class[] mParameterTypes = getParameterTypes(m);
1367:
1368:                            if (mParameterTypes.length == 1) {
1369:                                result = m;
1370:                                break;
1371:                            }
1372:                        }
1373:                    }
1374:                } else {
1375:                    result = pd.getWriteMethod();
1376:                }
1377:                return result;
1378:            }
1379:
1380:            public static final boolean hasSetMethod(OgnlContext context,
1381:                    Object target, Class targetClass, String propertyName)
1382:                    throws IntrospectionException, OgnlException {
1383:                return isMethodAccessible(context, target, getSetMethod(
1384:                        context, targetClass, propertyName), propertyName);
1385:            }
1386:
1387:            public static final boolean hasGetProperty(OgnlContext context,
1388:                    Object target, Object oname) throws IntrospectionException,
1389:                    OgnlException {
1390:                Class targetClass = (target == null) ? null : target.getClass();
1391:                String name = oname.toString();
1392:
1393:                return hasGetMethod(context, target, targetClass, name)
1394:                        || hasField(context, target, targetClass, name);
1395:            }
1396:
1397:            public static final boolean hasSetProperty(OgnlContext context,
1398:                    Object target, Object oname) throws IntrospectionException,
1399:                    OgnlException {
1400:                Class targetClass = (target == null) ? null : target.getClass();
1401:                String name = oname.toString();
1402:
1403:                return hasSetMethod(context, target, targetClass, name)
1404:                        || hasField(context, target, targetClass, name);
1405:            }
1406:
1407:            private static final boolean indexMethodCheck(List methods) {
1408:                boolean result = false;
1409:
1410:                if (methods.size() > 0) {
1411:                    Method fm = (Method) methods.get(0);
1412:                    Class[] fmpt = getParameterTypes(fm);
1413:                    int fmpc = fmpt.length;
1414:                    Class lastMethodClass = fm.getDeclaringClass();
1415:
1416:                    result = true;
1417:                    for (int i = 1; result && (i < methods.size()); i++) {
1418:                        Method m = (Method) methods.get(i);
1419:                        Class c = m.getDeclaringClass();
1420:
1421:                        // Check to see if more than one method implemented per class
1422:                        if (lastMethodClass == c) {
1423:                            result = false;
1424:                        } else {
1425:                            Class[] mpt = getParameterTypes(fm);
1426:                            int mpc = fmpt.length;
1427:
1428:                            if (fmpc != mpc) {
1429:                                result = false;
1430:                            }
1431:                            for (int j = 0; j < fmpc; j++) {
1432:                                if (fmpt[j] != mpt[j]) {
1433:                                    result = false;
1434:                                    break;
1435:                                }
1436:                            }
1437:                        }
1438:                        lastMethodClass = c;
1439:                    }
1440:                }
1441:                return result;
1442:            }
1443:
1444:            private static final void findObjectIndexedPropertyDescriptors(
1445:                    Class targetClass, Map intoMap) throws OgnlException {
1446:                Map allMethods = getMethods(targetClass, false);
1447:                Map pairs = new HashMap(101);
1448:
1449:                for (Iterator it = allMethods.keySet().iterator(); it.hasNext();) {
1450:                    String methodName = (String) it.next();
1451:                    List methods = (List) allMethods.get(methodName);
1452:
1453:                    /*
1454:                        Only process set/get where there is exactly one implementation
1455:                        of the method per class and those implementations are all the
1456:                        same
1457:                     */
1458:                    if (indexMethodCheck(methods)) {
1459:                        boolean isGet = false, isSet = false;
1460:                        Method m = (Method) methods.get(0);
1461:
1462:                        if (((isSet = methodName.startsWith(SET_PREFIX)) || (isGet = methodName
1463:                                .startsWith(GET_PREFIX)))
1464:                                && (methodName.length() > 3)) {
1465:                            String propertyName = Introspector
1466:                                    .decapitalize(methodName.substring(3));
1467:                            Class[] parameterTypes = getParameterTypes(m);
1468:                            int parameterCount = parameterTypes.length;
1469:
1470:                            if (isGet && (parameterCount == 1)
1471:                                    && (m.getReturnType() != Void.TYPE)) {
1472:                                List pair = (List) pairs.get(propertyName);
1473:
1474:                                if (pair == null) {
1475:                                    pairs.put(propertyName,
1476:                                            pair = new ArrayList());
1477:                                }
1478:                                pair.add(m);
1479:                            }
1480:                            if (isSet && (parameterCount == 2)
1481:                                    && (m.getReturnType() == Void.TYPE)) {
1482:                                List pair = (List) pairs.get(propertyName);
1483:
1484:                                if (pair == null) {
1485:                                    pairs.put(propertyName,
1486:                                            pair = new ArrayList());
1487:                                }
1488:                                pair.add(m);
1489:                            }
1490:                        }
1491:                    }
1492:                }
1493:                for (Iterator it = pairs.keySet().iterator(); it.hasNext();) {
1494:                    String propertyName = (String) it.next();
1495:                    List methods = (List) pairs.get(propertyName);
1496:
1497:                    if (methods.size() == 2) {
1498:                        Method method1 = (Method) methods.get(0), method2 = (Method) methods
1499:                                .get(1), setMethod = (method1
1500:                                .getParameterTypes().length == 2) ? method1
1501:                                : method2, getMethod = (setMethod == method1) ? method2
1502:                                : method1;
1503:                        Class keyType = getMethod.getParameterTypes()[0], propertyType = getMethod
1504:                                .getReturnType();
1505:
1506:                        if (keyType == setMethod.getParameterTypes()[0]) {
1507:                            if (propertyType == setMethod.getParameterTypes()[1]) {
1508:                                ObjectIndexedPropertyDescriptor propertyDescriptor;
1509:
1510:                                try {
1511:                                    propertyDescriptor = new ObjectIndexedPropertyDescriptor(
1512:                                            propertyName, propertyType,
1513:                                            getMethod, setMethod);
1514:                                } catch (Exception ex) {
1515:                                    throw new OgnlException(
1516:                                            "creating object indexed property descriptor for '"
1517:                                                    + propertyName + "' in "
1518:                                                    + targetClass, ex);
1519:                                }
1520:                                intoMap.put(propertyName, propertyDescriptor);
1521:                            }
1522:                        }
1523:
1524:                    }
1525:                }
1526:            }
1527:
1528:            /**
1529:                This method returns the property descriptors for the given class as a Map
1530:             */
1531:            public static final Map getPropertyDescriptors(Class targetClass)
1532:                    throws IntrospectionException, OgnlException {
1533:                Map result;
1534:
1535:                synchronized (propertyDescriptorCache) {
1536:                    if ((result = (Map) propertyDescriptorCache
1537:                            .get(targetClass)) == null) {
1538:                        PropertyDescriptor[] pda = Introspector.getBeanInfo(
1539:                                targetClass).getPropertyDescriptors();
1540:
1541:                        result = new HashMap(101);
1542:                        for (int i = 0, icount = pda.length; i < icount; i++) {
1543:                            result.put(pda[i].getName(), pda[i]);
1544:                        }
1545:                        findObjectIndexedPropertyDescriptors(targetClass,
1546:                                result);
1547:                        propertyDescriptorCache.put(targetClass, result);
1548:                    }
1549:                }
1550:                return result;
1551:            }
1552:
1553:            /**
1554:                This method returns a PropertyDescriptor for the given class and property name using
1555:                a Map lookup (using getPropertyDescriptorsMap()).
1556:             */
1557:            public static final PropertyDescriptor getPropertyDescriptor(
1558:                    Class targetClass, String propertyName)
1559:                    throws IntrospectionException, OgnlException {
1560:                return (targetClass == null) ? null
1561:                        : (PropertyDescriptor) getPropertyDescriptors(
1562:                                targetClass).get(propertyName);
1563:            }
1564:
1565:            public static final PropertyDescriptor[] getPropertyDescriptorsArray(
1566:                    Class targetClass) throws IntrospectionException {
1567:                PropertyDescriptor[] result = null;
1568:
1569:                if (targetClass != null) {
1570:                    synchronized (propertyDescriptorCache) {
1571:                        if ((result = (PropertyDescriptor[]) propertyDescriptorCache
1572:                                .get(targetClass)) == null) {
1573:                            propertyDescriptorCache.put(targetClass,
1574:                                    result = Introspector.getBeanInfo(
1575:                                            targetClass)
1576:                                            .getPropertyDescriptors());
1577:                        }
1578:                    }
1579:                }
1580:                return result;
1581:            }
1582:
1583:            /**
1584:                Gets the property descriptor with the given name for the target class given.
1585:                @param targetClass      Class for which property descriptor is desired
1586:                @param name             Name of property
1587:                @return                 PropertyDescriptor of the named property or null if
1588:                                        the class has no property with the given name
1589:             */
1590:            public static final PropertyDescriptor getPropertyDescriptorFromArray(
1591:                    Class targetClass, String name)
1592:                    throws IntrospectionException {
1593:                PropertyDescriptor result = null;
1594:                PropertyDescriptor[] pda = getPropertyDescriptorsArray(targetClass);
1595:
1596:                for (int i = 0, icount = pda.length; (result == null)
1597:                        && (i < icount); i++) {
1598:                    if (pda[i].getName().compareTo(name) == 0) {
1599:                        result = pda[i];
1600:                    }
1601:                }
1602:                return result;
1603:            }
1604:
1605:            public static final void setMethodAccessor(Class cls,
1606:                    MethodAccessor accessor) {
1607:                synchronized (methodAccessors) {
1608:                    methodAccessors.put(cls, accessor);
1609:                }
1610:            }
1611:
1612:            public static final MethodAccessor getMethodAccessor(Class cls)
1613:                    throws OgnlException {
1614:                MethodAccessor answer = (MethodAccessor) getHandler(cls,
1615:                        methodAccessors);
1616:                if (answer != null)
1617:                    return answer;
1618:                throw new OgnlException("No method accessor for " + cls);
1619:            }
1620:
1621:            public static final void setPropertyAccessor(Class cls,
1622:                    PropertyAccessor accessor) {
1623:                synchronized (propertyAccessors) {
1624:                    propertyAccessors.put(cls, accessor);
1625:                }
1626:            }
1627:
1628:            public static final PropertyAccessor getPropertyAccessor(Class cls)
1629:                    throws OgnlException {
1630:                PropertyAccessor answer = (PropertyAccessor) getHandler(cls,
1631:                        propertyAccessors);
1632:                if (answer != null)
1633:                    return answer;
1634:
1635:                throw new OgnlException("No property accessor for class " + cls);
1636:            }
1637:
1638:            public static final ElementsAccessor getElementsAccessor(Class cls)
1639:                    throws OgnlException {
1640:                ElementsAccessor answer = (ElementsAccessor) getHandler(cls,
1641:                        elementsAccessors);
1642:                if (answer != null)
1643:                    return answer;
1644:                throw new OgnlException("No elements accessor for class " + cls);
1645:            }
1646:
1647:            public static final void setElementsAccessor(Class cls,
1648:                    ElementsAccessor accessor) {
1649:                synchronized (elementsAccessors) {
1650:                    elementsAccessors.put(cls, accessor);
1651:                }
1652:            }
1653:
1654:            public static final NullHandler getNullHandler(Class cls)
1655:                    throws OgnlException {
1656:                NullHandler answer = (NullHandler) getHandler(cls, nullHandlers);
1657:                if (answer != null)
1658:                    return answer;
1659:                throw new OgnlException("No null handler for class " + cls);
1660:            }
1661:
1662:            public static final void setNullHandler(Class cls,
1663:                    NullHandler handler) {
1664:                synchronized (nullHandlers) {
1665:                    nullHandlers.put(cls, handler);
1666:                }
1667:            }
1668:
1669:            private static final Object getHandler(Class forClass,
1670:                    ClassCache handlers) {
1671:                Object answer = null;
1672:
1673:                synchronized (handlers) {
1674:                    if ((answer = handlers.get(forClass)) == null) {
1675:                        Class keyFound;
1676:
1677:                        if (forClass.isArray()) {
1678:                            answer = handlers.get(Object[].class);
1679:                            keyFound = null;
1680:                        } else {
1681:                            keyFound = forClass;
1682:                            outer: for (Class c = forClass; c != null; c = c
1683:                                    .getSuperclass()) {
1684:                                answer = handlers.get(c);
1685:                                if (answer == null) {
1686:                                    Class[] interfaces = c.getInterfaces();
1687:                                    for (int index = 0, count = interfaces.length; index < count; ++index) {
1688:                                        Class iface = interfaces[index];
1689:
1690:                                        answer = handlers.get(iface);
1691:                                        if (answer == null) {
1692:                                            /* Try super-interfaces */
1693:                                            answer = getHandler(iface, handlers);
1694:                                        }
1695:                                        if (answer != null) {
1696:                                            keyFound = iface;
1697:                                            break outer;
1698:                                        }
1699:                                    }
1700:                                } else {
1701:                                    keyFound = c;
1702:                                    break;
1703:                                }
1704:                            }
1705:                        }
1706:                        if (answer != null) {
1707:                            if (keyFound != forClass) {
1708:                                handlers.put(forClass, answer);
1709:                            }
1710:                        }
1711:                    }
1712:                }
1713:                return answer;
1714:            }
1715:
1716:            public static final Object getProperty(OgnlContext context,
1717:                    Object source, Object name) throws OgnlException {
1718:                PropertyAccessor accessor;
1719:
1720:                if (source == null) {
1721:                    throw new OgnlException(
1722:                            "source is null for getProperty(null, \"" + name
1723:                                    + "\")");
1724:                }
1725:                if ((accessor = getPropertyAccessor(getTargetClass(source))) == null) {
1726:                    throw new OgnlException("No property accessor for "
1727:                            + getTargetClass(source).getName());
1728:                }
1729:                return accessor.getProperty(context, source, name);
1730:            }
1731:
1732:            public static final void setProperty(OgnlContext context,
1733:                    Object target, Object name, Object value)
1734:                    throws OgnlException {
1735:                PropertyAccessor accessor;
1736:
1737:                if (target == null) {
1738:                    throw new OgnlException(
1739:                            "target is null for setProperty(null, \"" + name
1740:                                    + "\", " + value + ")");
1741:                }
1742:                if ((accessor = getPropertyAccessor(getTargetClass(target))) == null) {
1743:                    throw new OgnlException("No property accessor for "
1744:                            + getTargetClass(target).getName());
1745:                }
1746:                accessor.setProperty(context, target, name, value);
1747:            }
1748:
1749:            /**
1750:                Determines the index property type, if any.  Returns <code>INDEXED_PROPERTY_NONE</code> if the
1751:                property is not index-accessible as determined by OGNL or JavaBeans.  If it is indexable
1752:                then this will return whether it is a JavaBeans indexed property, conforming to the
1753:                indexed property patterns (returns <code>INDEXED_PROPERTY_INT</code>) or if it conforms
1754:                to the OGNL arbitrary object indexable (returns <code>INDEXED_PROPERTY_OBJECT</code>).
1755:             */
1756:            public static final int getIndexedPropertyType(OgnlContext context,
1757:                    Class sourceClass, String name) throws OgnlException {
1758:                int result = INDEXED_PROPERTY_NONE;
1759:
1760:                try {
1761:                    PropertyDescriptor pd = getPropertyDescriptor(sourceClass,
1762:                            name);
1763:
1764:                    if (pd != null) {
1765:                        if (pd instanceof  IndexedPropertyDescriptor) {
1766:                            result = INDEXED_PROPERTY_INT;
1767:                        } else {
1768:                            if (pd instanceof  ObjectIndexedPropertyDescriptor) {
1769:                                result = INDEXED_PROPERTY_OBJECT;
1770:                            }
1771:                        }
1772:                    }
1773:                } catch (Exception ex) {
1774:                    throw new OgnlException("problem determining if '" + name
1775:                            + "' is an indexed property", ex);
1776:                }
1777:                return result;
1778:            }
1779:
1780:            public static final Object getIndexedProperty(OgnlContext context,
1781:                    Object source, String name, Object index)
1782:                    throws OgnlException {
1783:                Throwable reason = null;
1784:                Object[] args = objectArrayPool.create(index);
1785:
1786:                try {
1787:                    PropertyDescriptor pd = getPropertyDescriptor(
1788:                            (source == null) ? null : source.getClass(), name);
1789:                    Method m;
1790:
1791:                    if (pd instanceof  IndexedPropertyDescriptor) {
1792:                        m = ((IndexedPropertyDescriptor) pd)
1793:                                .getIndexedReadMethod();
1794:                    } else {
1795:                        if (pd instanceof  ObjectIndexedPropertyDescriptor) {
1796:                            m = ((ObjectIndexedPropertyDescriptor) pd)
1797:                                    .getIndexedReadMethod();
1798:                        } else {
1799:                            throw new OgnlException("property '" + name
1800:                                    + "' is not an indexed property");
1801:                        }
1802:                    }
1803:                    return callMethod(context, source, m.getName(), name, args);
1804:                } catch (OgnlException ex) {
1805:                    throw ex;
1806:                } catch (Exception ex) {
1807:                    throw new OgnlException(
1808:                            "getting indexed property descriptor for '" + name
1809:                                    + "'", ex);
1810:                } finally {
1811:                    objectArrayPool.recycle(args);
1812:                }
1813:            }
1814:
1815:            public static final void setIndexedProperty(OgnlContext context,
1816:                    Object source, String name, Object index, Object value)
1817:                    throws OgnlException {
1818:                Throwable reason = null;
1819:                Object[] args = objectArrayPool.create(index, value);
1820:
1821:                try {
1822:                    PropertyDescriptor pd = getPropertyDescriptor(
1823:                            (source == null) ? null : source.getClass(), name);
1824:                    Method m;
1825:
1826:                    if (pd instanceof  IndexedPropertyDescriptor) {
1827:                        m = ((IndexedPropertyDescriptor) pd)
1828:                                .getIndexedWriteMethod();
1829:                    } else {
1830:                        if (pd instanceof  ObjectIndexedPropertyDescriptor) {
1831:                            m = ((ObjectIndexedPropertyDescriptor) pd)
1832:                                    .getIndexedWriteMethod();
1833:                        } else {
1834:                            throw new OgnlException("property '" + name
1835:                                    + "' is not an indexed property");
1836:                        }
1837:                    }
1838:                    callMethod(context, source, m.getName(), name, args);
1839:                } catch (OgnlException ex) {
1840:                    throw ex;
1841:                } catch (Exception ex) {
1842:                    throw new OgnlException(
1843:                            "getting indexed property descriptor for '" + name
1844:                                    + "'", ex);
1845:                } finally {
1846:                    objectArrayPool.recycle(args);
1847:                }
1848:            }
1849:
1850:            public static EvaluationPool getEvaluationPool() {
1851:                return evaluationPool;
1852:            }
1853:
1854:            public static ObjectArrayPool getObjectArrayPool() {
1855:                return objectArrayPool;
1856:            }
1857:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.