001: //========================================================================
002: //$Id: IntrospectionUtil.java 1448 2006-12-29 20:46:57Z janb $
003: //Copyright 2006 Mort Bay Consulting Pty. Ltd.
004: //------------------------------------------------------------------------
005: //Licensed under the Apache License, Version 2.0 (the "License");
006: //you may not use this file except in compliance with the License.
007: //You may obtain a copy of the License at
008: //http://www.apache.org/licenses/LICENSE-2.0
009: //Unless required by applicable law or agreed to in writing, software
010: //distributed under the License is distributed on an "AS IS" BASIS,
011: //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: //See the License for the specific language governing permissions and
013: //limitations under the License.
014: //========================================================================
015:
016: package org.mortbay.util;
017:
018: import java.lang.reflect.Field;
019: import java.lang.reflect.Member;
020: import java.lang.reflect.Method;
021: import java.lang.reflect.Modifier;
022:
023: /**
024: * IntrospectionUtil
025: *
026: *
027: */
028: public class IntrospectionUtil {
029:
030: public static Method findMethod(Class clazz, String methodName,
031: Class[] args, boolean checkInheritance, boolean strictArgs)
032: throws NoSuchMethodException {
033: if (clazz == null)
034: throw new NoSuchMethodException("No class");
035: if (methodName == null || methodName.trim().equals(""))
036: throw new NoSuchMethodException("No method name");
037:
038: Method method = null;
039: Method[] methods = clazz.getDeclaredMethods();
040: for (int i = 0; i < methods.length && method == null; i++) {
041: if (methods[i].getName().equals(methodName)
042: && checkParams(methods[i].getParameterTypes(),
043: (args == null ? new Class[] {} : args),
044: strictArgs)) {
045: method = methods[i];
046: }
047:
048: }
049: if (method != null) {
050: return method;
051: } else if (checkInheritance)
052: return findInheritedMethod(clazz.getPackage(), clazz
053: .getSuperclass(), methodName, args, strictArgs);
054: else
055: throw new NoSuchMethodException("No such method "
056: + methodName + " on class " + clazz.getName());
057:
058: }
059:
060: public static Field findField(Class clazz, String targetName,
061: Class targetType, boolean checkInheritance,
062: boolean strictType) throws NoSuchFieldException {
063: if (clazz == null)
064: throw new NoSuchFieldException("No class");
065: if (targetName == null)
066: throw new NoSuchFieldException("No field name");
067:
068: try {
069: Field field = clazz.getDeclaredField(targetName);
070: if (strictType) {
071: if (field.getType().equals(targetType))
072: return field;
073: } else {
074: if (field.getType().isAssignableFrom(targetType))
075: return field;
076: }
077: if (checkInheritance) {
078: return findInheritedField(clazz.getPackage(), clazz
079: .getSuperclass(), targetName, targetType,
080: strictType);
081: } else
082: throw new NoSuchFieldException("No field with name "
083: + targetName + " in class " + clazz.getName()
084: + " of type " + targetType);
085: } catch (NoSuchFieldException e) {
086: return findInheritedField(clazz.getPackage(), clazz
087: .getSuperclass(), targetName, targetType,
088: strictType);
089: }
090: }
091:
092: public static boolean checkInheritable(Package pack, Member member) {
093: if (pack == null)
094: return false;
095: if (member == null)
096: return false;
097:
098: int modifiers = member.getModifiers();
099: if (Modifier.isPublic(modifiers))
100: return true;
101: if (Modifier.isProtected(modifiers))
102: return true;
103: if (!Modifier.isPrivate(modifiers)
104: && pack.equals(member.getDeclaringClass().getPackage()))
105: return true;
106:
107: return false;
108: }
109:
110: public static boolean checkParams(Class[] formalParams,
111: Class[] actualParams, boolean strict) {
112: if (formalParams == null && actualParams == null)
113: return true;
114: if (formalParams == null && actualParams != null)
115: return false;
116: if (formalParams != null && actualParams == null)
117: return false;
118:
119: if (formalParams.length != actualParams.length)
120: return false;
121:
122: if (formalParams.length == 0)
123: return true;
124:
125: int j = 0;
126: if (strict) {
127: while (j < formalParams.length
128: && formalParams[j].equals(actualParams[j]))
129: j++;
130: } else {
131: while ((j < formalParams.length)
132: && (formalParams[j]
133: .isAssignableFrom(actualParams[j]))) {
134: j++;
135: }
136: }
137:
138: if (j != formalParams.length) {
139: return false;
140: }
141:
142: return true;
143: }
144:
145: public static boolean checkType(Class formalType, Class actualType,
146: boolean strict) {
147: if (formalType == null && actualType != null)
148: return false;
149: if (formalType != null && actualType == null)
150: return false;
151: if (formalType == null && actualType == null)
152: return true;
153:
154: if (strict)
155: return formalType.equals(actualType);
156: else
157: return formalType.isAssignableFrom(actualType);
158: }
159:
160: protected static Method findInheritedMethod(Package pack,
161: Class clazz, String methodName, Class[] args,
162: boolean strictArgs) throws NoSuchMethodException {
163: if (clazz == null)
164: throw new NoSuchMethodException("No class");
165: if (methodName == null)
166: throw new NoSuchMethodException("No method name");
167:
168: Method method = null;
169: Method[] methods = clazz.getDeclaredMethods();
170: for (int i = 0; i < methods.length && method == null; i++) {
171: if (methods[i].getName().equals(methodName)
172: && checkInheritable(pack, methods[i])
173: && checkParams(methods[i].getParameterTypes(),
174: args, strictArgs))
175: method = methods[i];
176: }
177: if (method != null) {
178: return method;
179: } else
180: return findInheritedMethod(clazz.getPackage(), clazz
181: .getSuperclass(), methodName, args, strictArgs);
182: }
183:
184: protected static Field findInheritedField(Package pack,
185: Class clazz, String fieldName, Class fieldType,
186: boolean strictType) throws NoSuchFieldException {
187: if (clazz == null)
188: throw new NoSuchFieldException("No class");
189: if (fieldName == null)
190: throw new NoSuchFieldException("No field name");
191: try {
192: Field field = clazz.getDeclaredField(fieldName);
193: if (checkInheritable(pack, field)
194: && checkType(fieldType, field.getType(), strictType))
195: return field;
196: else
197: return findInheritedField(clazz.getPackage(), clazz
198: .getSuperclass(), fieldName, fieldType,
199: strictType);
200: } catch (NoSuchFieldException e) {
201: return findInheritedField(clazz.getPackage(), clazz
202: .getSuperclass(), fieldName, fieldType, strictType);
203: }
204: }
205:
206: }
|