001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.el.util;
018:
019: import java.beans.IntrospectionException;
020: import java.beans.Introspector;
021: import java.beans.PropertyDescriptor;
022: import java.lang.reflect.Array;
023: import java.lang.reflect.Method;
024: import java.util.Arrays;
025:
026: import javax.el.ELException;
027: import javax.el.MethodNotFoundException;
028: import javax.el.PropertyNotFoundException;
029:
030: import org.apache.el.lang.ELSupport;
031:
032: /**
033: * Utilities for Managing Serialization and Reflection
034: *
035: * @author Jacob Hookom [jacob@hookom.net]
036: * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: markt $
037: */
038: public class ReflectionUtil {
039:
040: protected static final String[] EMPTY_STRING = new String[0];
041:
042: protected static final String[] PRIMITIVE_NAMES = new String[] {
043: "boolean", "byte", "char", "double", "float", "int",
044: "long", "short", "void" };
045:
046: protected static final Class[] PRIMITIVES = new Class[] {
047: boolean.class, byte.class, char.class, double.class,
048: float.class, int.class, long.class, short.class, Void.TYPE };
049:
050: /**
051: *
052: */
053: private ReflectionUtil() {
054: super ();
055: }
056:
057: public static Class forName(String name)
058: throws ClassNotFoundException {
059: if (null == name || "".equals(name)) {
060: return null;
061: }
062: Class c = forNamePrimitive(name);
063: if (c == null) {
064: if (name.endsWith("[]")) {
065: String nc = name.substring(0, name.length() - 2);
066: c = Class.forName(nc, true, Thread.currentThread()
067: .getContextClassLoader());
068: c = Array.newInstance(c, 0).getClass();
069: } else {
070: c = Class.forName(name, true, Thread.currentThread()
071: .getContextClassLoader());
072: }
073: }
074: return c;
075: }
076:
077: protected static Class forNamePrimitive(String name) {
078: if (name.length() <= 8) {
079: int p = Arrays.binarySearch(PRIMITIVE_NAMES, name);
080: if (p >= 0) {
081: return PRIMITIVES[p];
082: }
083: }
084: return null;
085: }
086:
087: /**
088: * Converts an array of Class names to Class types
089: * @param s
090: * @return
091: * @throws ClassNotFoundException
092: */
093: public static Class[] toTypeArray(String[] s)
094: throws ClassNotFoundException {
095: if (s == null)
096: return null;
097: Class[] c = new Class[s.length];
098: for (int i = 0; i < s.length; i++) {
099: c[i] = forName(s[i]);
100: }
101: return c;
102: }
103:
104: /**
105: * Converts an array of Class types to Class names
106: * @param c
107: * @return
108: */
109: public static String[] toTypeNameArray(Class[] c) {
110: if (c == null)
111: return null;
112: String[] s = new String[c.length];
113: for (int i = 0; i < c.length; i++) {
114: s[i] = c[i].getName();
115: }
116: return s;
117: }
118:
119: /**
120: * Returns a method based on the criteria
121: * @param base the object that owns the method
122: * @param property the name of the method
123: * @param paramTypes the parameter types to use
124: * @return the method specified
125: * @throws MethodNotFoundException
126: */
127: public static Method getMethod(Object base, Object property,
128: Class[] paramTypes) throws MethodNotFoundException {
129: if (base == null || property == null) {
130: throw new MethodNotFoundException(MessageFactory.get(
131: "error.method.notfound", base, property,
132: paramString(paramTypes)));
133: }
134:
135: String methodName = (property instanceof String) ? (String) property
136: : property.toString();
137:
138: Method method = null;
139: try {
140: method = base.getClass().getMethod(methodName, paramTypes);
141: } catch (NoSuchMethodException nsme) {
142: throw new MethodNotFoundException(MessageFactory.get(
143: "error.method.notfound", base, property,
144: paramString(paramTypes)));
145: }
146: return method;
147: }
148:
149: protected static final String paramString(Class[] types) {
150: if (types != null) {
151: StringBuffer sb = new StringBuffer();
152: for (int i = 0; i < types.length; i++) {
153: sb.append(types[i].getName()).append(", ");
154: }
155: if (sb.length() > 2) {
156: sb.setLength(sb.length() - 2);
157: }
158: return sb.toString();
159: }
160: return null;
161: }
162:
163: /**
164: * @param base
165: * @param property
166: * @return
167: * @throws ELException
168: * @throws PropertyNotFoundException
169: */
170: public static PropertyDescriptor getPropertyDescriptor(Object base,
171: Object property) throws ELException,
172: PropertyNotFoundException {
173: String name = ELSupport.coerceToString(property);
174: PropertyDescriptor p = null;
175: try {
176: PropertyDescriptor[] desc = Introspector.getBeanInfo(
177: base.getClass()).getPropertyDescriptors();
178: for (int i = 0; i < desc.length; i++) {
179: if (desc[i].getName().equals(name)) {
180: return desc[i];
181: }
182: }
183: } catch (IntrospectionException ie) {
184: throw new ELException(ie);
185: }
186: throw new PropertyNotFoundException(MessageFactory.get(
187: "error.property.notfound", base, name));
188: }
189: }
|