| %line | %branch | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| org.apache.commons.jexl.util.introspection.IntrospectorBase |
|
|
| 1 | /* |
|
| 2 | * Copyright 2001,2004 The Apache Software Foundation. |
|
| 3 | * |
|
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
|
| 5 | * you may not use this file except in compliance with the License. |
|
| 6 | * You may obtain a copy of the License at |
|
| 7 | * |
|
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 9 | * |
|
| 10 | * Unless required by applicable law or agreed to in writing, software |
|
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 13 | * See the License for the specific language governing permissions and |
|
| 14 | * limitations under the License. |
|
| 15 | */ |
|
| 16 | ||
| 17 | package org.apache.commons.jexl.util.introspection; |
|
| 18 | ||
| 19 | import java.util.Map; |
|
| 20 | import java.util.Set; |
|
| 21 | import java.util.HashMap; |
|
| 22 | import java.util.HashSet; |
|
| 23 | ||
| 24 | import java.lang.reflect.Method; |
|
| 25 | ||
| 26 | /** |
|
| 27 | * This basic function of this class is to return a Method object for a |
|
| 28 | * particular class given the name of a method and the parameters to the method |
|
| 29 | * in the form of an Object[] |
|
| 30 | * |
|
| 31 | * The first time the Introspector sees a class it creates a class method map |
|
| 32 | * for the class in question. Basically the class method map is a Hastable where |
|
| 33 | * Method objects are keyed by a concatenation of the method name and the names |
|
| 34 | * of classes that make up the parameters. |
|
| 35 | * |
|
| 36 | * For example, a method with the following signature: |
|
| 37 | * |
|
| 38 | * public void method(String a, StringBuffer b) |
|
| 39 | * |
|
| 40 | * would be mapped by the key: |
|
| 41 | * |
|
| 42 | * "method" + "java.lang.String" + "java.lang.StringBuffer" |
|
| 43 | * |
|
| 44 | * This mapping is performed for all the methods in a class and stored for |
|
| 45 | * |
|
| 46 | * @since 1.0 |
|
| 47 | * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> |
|
| 48 | * @author <a href="mailto:bob@werken.com">Bob McWhirter</a> |
|
| 49 | * @author <a href="mailto:szegedia@freemail.hu">Attila Szegedi</a> |
|
| 50 | * @author <a href="mailto:paulo.gaspar@krankikom.de">Paulo Gaspar</a> |
|
| 51 | * @version $Id: IntrospectorBase.java 398464 2006-04-30 23:50:43Z dion $ |
|
| 52 | */ |
|
| 53 | 8 | public class IntrospectorBase { |
| 54 | /** |
|
| 55 | * Holds the method maps for the classes we know about, keyed by Class |
|
| 56 | * object. |
|
| 57 | */ |
|
| 58 | 4 | protected Map classMethodMaps = new HashMap(); |
| 59 | ||
| 60 | /** |
|
| 61 | * Holds the qualified class names for the classes we hold in the |
|
| 62 | * classMethodMaps hash. |
|
| 63 | */ |
|
| 64 | 4 | protected Set cachedClassNames = new HashSet(); |
| 65 | ||
| 66 | /** |
|
| 67 | * Gets the method defined by <code>name</code> and <code>params</code> |
|
| 68 | * for the Class <code>c</code>. |
|
| 69 | * |
|
| 70 | * @param c Class in which the method search is taking place |
|
| 71 | * @param name Name of the method being searched for |
|
| 72 | * @param params An array of Objects (not Classes) that describe the the |
|
| 73 | * parameters |
|
| 74 | * |
|
| 75 | * @return The desired Method object. |
|
| 76 | * @throws Exception on any logical error. |
|
| 77 | */ |
|
| 78 | public Method getMethod(Class c, String name, Object[] params) throws Exception { |
|
| 79 | 98 | if (c == null) { |
| 80 | 0 | throw new Exception("Introspector.getMethod(): Class method key was null: " + name); |
| 81 | } |
|
| 82 | ||
| 83 | 98 | ClassMap classMap = null; |
| 84 | ||
| 85 | 98 | synchronized (classMethodMaps) { |
| 86 | 98 | classMap = (ClassMap) classMethodMaps.get(c); |
| 87 | ||
| 88 | /* |
|
| 89 | * if we don't have this, check to see if we have it by name. if so, |
|
| 90 | * then we have a classloader change so dump our caches. |
|
| 91 | */ |
|
| 92 | ||
| 93 | 98 | if (classMap == null) { |
| 94 | 10 | if (cachedClassNames.contains(c.getName())) { |
| 95 | /* |
|
| 96 | * we have a map for a class with same name, but not this |
|
| 97 | * class we are looking at. This implies a classloader |
|
| 98 | * change, so dump |
|
| 99 | */ |
|
| 100 | 0 | clearCache(); |
| 101 | } |
|
| 102 | ||
| 103 | 10 | classMap = createClassMap(c); |
| 104 | } |
|
| 105 | 98 | } |
| 106 | ||
| 107 | 98 | return classMap.findMethod(name, params); |
| 108 | } |
|
| 109 | ||
| 110 | /** |
|
| 111 | * Creates a class map for specific class and registers it in the cache. |
|
| 112 | * Also adds the qualified name to the name->class map for later Classloader |
|
| 113 | * change detection. |
|
| 114 | * @param c class. |
|
| 115 | * @return a {@link ClassMap} |
|
| 116 | */ |
|
| 117 | protected ClassMap createClassMap(Class c) { |
|
| 118 | 10 | ClassMap classMap = new ClassMap(c); |
| 119 | 10 | classMethodMaps.put(c, classMap); |
| 120 | 10 | cachedClassNames.add(c.getName()); |
| 121 | ||
| 122 | 10 | return classMap; |
| 123 | } |
|
| 124 | ||
| 125 | /** |
|
| 126 | * Clears the classmap and classname caches. |
|
| 127 | */ |
|
| 128 | protected void clearCache() { |
|
| 129 | /* |
|
| 130 | * since we are synchronizing on this object, we have to clear it rather |
|
| 131 | * than just dump it. |
|
| 132 | */ |
|
| 133 | 0 | classMethodMaps.clear(); |
| 134 | ||
| 135 | /* |
|
| 136 | * for speed, we can just make a new one and let the old one be GC'd |
|
| 137 | */ |
|
| 138 | 0 | cachedClassNames = new HashSet(); |
| 139 | 0 | } |
| 140 | } |
| This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |