001: /* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
002: * This code is licensed under the GPL 2.0 license, availible at the root
003: * application directory.
004: */
005: package org.geoserver.ows.util;
006:
007: import java.lang.reflect.Method;
008:
009: /**
010: * Utility class for performing reflective operations.
011: *
012: * @author Justin Deoliveira, The Open Planning Project
013: *
014: */
015: public class OwsUtils {
016:
017: /**
018: * Returns a setter method for a property of java bean.
019: * <p>
020: * The <tt>type</tt> parameter may be <code>null</code> to indicate the
021: * the setter for the property should be returned regardless of the type. If
022: * not null it will be used to filter the returned method.
023: * </p>
024: * @param clazz The type of the bean.
025: * @param property The property name.
026: * @param type The type of the property, may be <code>null</code>.
027: *
028: * @return The setter method, or <code>null</code> if not found.
029: */
030: public static Method setter(Class clazz, String property, Class type) {
031: //TODO: this lookup doesn't deal with classes that might have two setters
032: // that are in the same class hierachy
033: Method[] methods = clazz.getMethods();
034:
035: final String methodName = "set" + property;
036: for (int i = 0; i < methods.length; i++) {
037: Method method = methods[i];
038:
039: if (method.getName().equalsIgnoreCase(methodName)) {
040: if (method.getParameterTypes().length == 1) {
041: if (type != null) {
042: if (method.getParameterTypes()[0]
043: .isAssignableFrom(type)) {
044: return method;
045: }
046: } else {
047: return method;
048: }
049: }
050: }
051: }
052:
053: //nto found, check for case where setter property is primtive and the
054: // class specified is its wrapper class
055: if (type != null) {
056: for (int i = 0; i < methods.length; i++) {
057: Method method = methods[i];
058:
059: if (method.getName().equalsIgnoreCase(methodName)) {
060: if ((method.getParameterTypes().length == 1)) {
061: Class target = method.getParameterTypes()[0];
062: if (target.isPrimitive()
063: && type == wrapper(target)) {
064: return method;
065: }
066:
067: if (type.isPrimitive()
068: && target == wrapper(type)) {
069: return method;
070: }
071: }
072: }
073: }
074: }
075:
076: //could not be found, try again with a more lax match
077: String lax = lax(property);
078:
079: if (!lax.equals(property)) {
080: return setter(clazz, lax, type);
081: }
082:
083: return null;
084: }
085:
086: /**
087: * Returns a getter method for a property of java bean.
088: *
089: * @param clazz The type of the bean.
090: * @param property The property name.
091: * @param type The type of the property, may be null.
092: *
093: * @return The setter method, or <code>null</code> if not found.
094: */
095: public static Method getter(Class clazz, String property, Class type) {
096: //TODO: this lookup doesn't deal with classes that might have two setters
097: // that are in the same class hierachy
098: Method[] methods = clazz.getMethods();
099:
100: for (int i = 0; i < methods.length; i++) {
101: Method method = methods[i];
102:
103: if (method.getName().equalsIgnoreCase("get" + property)) {
104: if (type != null) {
105: if (type.equals(method.getReturnType())) {
106: return method;
107: }
108: } else {
109: return method;
110: }
111: }
112: }
113:
114: //check for case where one of the classes is primitive and the other
115: // is a wrapper
116: if (type != null) {
117: for (int i = 0; i < methods.length; i++) {
118: Method method = methods[i];
119:
120: if (method.getName().equalsIgnoreCase("get" + property)) {
121: Class target = method.getReturnType();
122: if (target != null) {
123:
124: if (target.isPrimitive()
125: && type == wrapper(target)) {
126: return method;
127: }
128: if (type.isPrimitive()
129: && target == wrapper(type)) {
130: return method;
131: }
132:
133: }
134: }
135: }
136: }
137:
138: //could not be found, try again with a more lax match
139: String lax = lax(property);
140:
141: if (!lax.equals(property)) {
142: return getter(clazz, lax, type);
143: }
144:
145: return null;
146: }
147:
148: /**
149: * Reflectivley retreives a propety from a java bean.
150: *
151: * @param object The java bean.
152: * @param property The property to retreive.
153: * @param type Teh type of the property to retreive.
154: *
155: * @return The property, or null if it could not be found..
156: */
157: public static Object property(Object object, String property,
158: Class type) {
159: Method getter = getter(object.getClass(), property, type);
160:
161: if (getter != null) {
162: try {
163: return getter.invoke(object, null);
164: } catch (Exception e) {
165: //TODO: log this
166: }
167: }
168:
169: return null;
170: }
171:
172: /**
173: * Returns a method with a pariticular name of a class, ignoring method
174: * paramters.
175: *
176: * @param clazz The class
177: * @param name The name of the method.
178: *
179: * @return The method, or <code>null</code> if it could not be found.
180: */
181: public static Method method(Class clazz, String name) {
182: Method[] methods = clazz.getMethods();
183:
184: for (int i = 0; i < methods.length; i++) {
185: Method method = methods[i];
186:
187: if (method.getName().equalsIgnoreCase(name)) {
188: return method;
189: }
190: }
191:
192: return null;
193: }
194:
195: /**
196: * Returns an object of a particular type in a list of objects of
197: * various types.
198: *
199: * @param parameters A list of objects, of various types.
200: * @param type The type of paramter to be returned.
201: *
202: * @return The object of the specified type, or <code>null</code>
203: */
204: public static Object parameter(Object[] parameters, Class type) {
205: for (int i = 0; i < parameters.length; i++) {
206: Object parameter = parameters[i];
207:
208: if ((parameter != null)
209: && type.isAssignableFrom(parameter.getClass())) {
210: return parameter;
211: }
212: }
213:
214: return null;
215: }
216:
217: /**
218: * Returns the wrapper class for a primitive class.
219: *
220: * @param primitive A primtive class, like int.class, double.class, etc...
221: */
222: static Class wrapper(Class primitive) {
223: if (boolean.class == primitive) {
224: return Boolean.class;
225: }
226: if (char.class == primitive) {
227: return Character.class;
228: }
229: if (byte.class == primitive) {
230: return Byte.class;
231: }
232: if (short.class == primitive) {
233: return Short.class;
234: }
235: if (int.class == primitive) {
236: return Integer.class;
237: }
238: if (long.class == primitive) {
239: return Long.class;
240: }
241:
242: if (float.class == primitive) {
243: return Float.class;
244: }
245: if (double.class == primitive) {
246: return Double.class;
247: }
248:
249: return null;
250: }
251:
252: /**
253: * Does some checks on the property name to turn it into a java bean property.
254: * <p>
255: * Checks include collapsing any "_" characters.
256: * </p>
257: */
258: static String lax(String property) {
259: return property.replaceAll("_", "");
260: }
261: }
|