001: /*
002: * Copyright 2007 Gerd Ziegler (www.gerdziegler.de)
003: * Licensed under the Apache License, Version 2.0 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at
006: * http://www.apache.org/licenses/LICENSE-2.0
007: * Unless required by applicable law or agreed to in writing,
008: * software distributed under the License is distributed on an
009: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
010: * either express or implied. See the License for the specific
011: * language governing permissions and limitations under the License.
012: * @author www.gerdziegler.de
013: */
014:
015: package org.ztemplates.actions.util;
016:
017: import java.lang.reflect.Method;
018: import java.util.Map;
019:
020: import org.apache.log4j.Logger;
021: import org.ztemplates.actions.ZAfter;
022: import org.ztemplates.actions.ZBefore;
023: import org.ztemplates.actions.ZGetter;
024: import org.ztemplates.actions.ZInit;
025: import org.ztemplates.actions.ZMatch;
026: import org.ztemplates.actions.ZSetter;
027: import org.ztemplates.property.ZProperty;
028: import org.ztemplates.property.ZPropertyUtil;
029:
030: public class ZReflectionUtil {
031: private static Logger log = Logger.getLogger(ZReflectionUtil.class);
032:
033: // *********************************************************************************
034: // *********************************************************************************
035: // *********************************************************************************
036:
037: public static void callAfter(Object obj) throws Exception {
038: ZPropertyUtil.revalidateAction(obj);
039: Method m = getAfter(obj.getClass(), "");
040: if (m != null) {
041: invoke(m, obj);
042: }
043: }
044:
045: public static void callAfterReference(Object obj, String name)
046: throws Exception {
047: Method m = getAfter(obj.getClass(), name);
048: if (m != null) {
049: invoke(m, obj);
050: }
051: }
052:
053: public static void callAfterVariable(Object obj, String name)
054: throws Exception {
055: Method m = getAfter(obj.getClass(), name);
056: if (m != null) {
057: invoke(m, obj);
058: }
059: }
060:
061: public static void callBefore(Object obj) throws Exception {
062: Method m = getBefore(obj.getClass(), "");
063: if (m != null) {
064: invoke(m, obj);
065: }
066: }
067:
068: public static void callBeforeReference(Object obj, String name)
069: throws Exception {
070: Method m = getBefore(obj.getClass(), name);
071: if (m != null) {
072: invoke(m, obj);
073: }
074: }
075:
076: public static void callBeforeVariable(Object obj, String name)
077: throws Exception {
078: Method m = getBefore(obj.getClass(), name);
079: if (m != null) {
080: invoke(m, obj);
081: }
082: }
083:
084: public static void callInitReference(Object obj, String name,
085: Object value) throws Exception {
086: Method m = getInit(obj.getClass(), name);
087: if (m != null) {
088: invoke(m, obj, value);
089: }
090: }
091:
092: public static void callParameterSetter(Object obj, String name,
093: String[] value) throws Exception {
094: Method m = getSetter(obj.getClass(), name);
095: if (m == null) {
096: throw new Exception("parameter setter not found: '" + name
097: + "' in " + obj.getClass().getName()
098: + " use annotation "
099: + ZSetter.class.getSimpleName());
100: }
101: if (ZProperty.class.isAssignableFrom(m.getReturnType())) {
102: ZProperty prop = (ZProperty) invoke(m, obj);
103: prop.setStringValue(value == null ? null : value[0]);
104: return;
105: }
106:
107: if (m.getParameterTypes()[0].isArray()) {
108: invoke(m, obj, (Object) value);
109: } else {
110: if (value == null) {
111: invoke(m, obj, (Object) null);
112: } else if (value.length == 1) {
113: String val = value[0];
114: if ("".equals(val)) {
115: val = null;
116: }
117: invoke(m, obj, val);
118: } else {
119: throw new Exception(
120: "cannot assign multiple values to non array setter: "
121: + m + " " + value);
122: }
123: }
124: }
125:
126: /**
127: * parameters are consumed depth first
128: *
129: * @param obj
130: * @param parameters
131: * @throws Exception
132: */
133: public static void setParametersAndConsumeAssigned(Object obj,
134: Map<String, String[]> parameters) throws Exception {
135: if (parameters.isEmpty()) {
136: return;
137: }
138: ZMatch match = (ZMatch) obj.getClass().getAnnotation(
139: ZMatch.class);
140: String[] parameterDefs = match.parameters();
141: for (String name : parameterDefs) {
142: String[] value = parameters.get(name);
143: ZReflectionUtil.callParameterSetter(obj, name, value);
144: // eat the parameters
145: parameters.remove(name);
146: }
147: }
148:
149: public static void callReferenceSetter(Object obj, String name,
150: Object value) throws Exception {
151: Method m = getSetter(obj.getClass(), name);
152: if (m == null) {
153: throw new Exception("reference setter not found: '" + name
154: + "' in " + obj.getClass().getName()
155: + " use annotation "
156: + ZSetter.class.getSimpleName());
157: }
158: invoke(m, obj, value);
159: }
160:
161: public static void callVariableSetter(Object obj, String name,
162: String value) throws Exception {
163: Method m = getSetter(obj.getClass(), name);
164: if (m == null) {
165: throw new Exception("variable setter not found: '" + name
166: + "' in " + obj.getClass().getName()
167: + " use annotation "
168: + ZSetter.class.getSimpleName());
169: }
170: if (ZProperty.class.isAssignableFrom(m.getReturnType())) {
171: ZProperty prop = (ZProperty) invoke(m, obj);
172: prop.setStringValue(value == null ? null : value);
173: } else {
174: invoke(m, obj, value);
175: }
176: }
177:
178: public static String[] callParameterGetter(Object obj, String name)
179: throws Exception {
180: Method m = getGetter(obj.getClass(), name);
181: if (m == null) {
182: throw new Exception("parameter getter not found: '" + name
183: + "' in " + obj.getClass().getName()
184: + " use annotation "
185: + ZGetter.class.getSimpleName());
186: }
187:
188: Object ret;
189: if (ZProperty.class.isAssignableFrom(m.getReturnType())) {
190: ZProperty prop = (ZProperty) invoke(m, obj);
191: ret = prop.getStringValue();
192: } else {
193: ret = invoke(m, obj);
194: }
195:
196: if (ret == null) {
197: return null;
198: }
199: if (ret.getClass().isArray()) {
200: return (String[]) ret;
201: }
202: return new String[] { (String) ret };
203: }
204:
205: public static Object callReferenceGetter(Object obj, String name)
206: throws Exception {
207: Method m = getGetter(obj.getClass(), name);
208: if (m == null) {
209: throw new Exception("reference getter not found: '" + name
210: + "' in " + obj.getClass().getName()
211: + " use annotation "
212: + ZGetter.class.getSimpleName());
213: }
214:
215: Object ret = invoke(m, obj);
216: return ret;
217: }
218:
219: public static String callVariableGetter(Object obj, String name)
220: throws Exception {
221: Method m = getGetter(obj.getClass(), name);
222: if (m == null) {
223: throw new Exception("variable getter not found: '" + name
224: + "' in " + obj.getClass().getName()
225: + " use annotation "
226: + ZGetter.class.getSimpleName());
227: }
228:
229: String ret;
230: if (ZProperty.class.isAssignableFrom(m.getReturnType())) {
231: ZProperty prop = (ZProperty) invoke(m, obj);
232: ret = prop.getStringValue();
233: } else {
234: ret = (String) invoke(m, obj);
235: }
236: return ret;
237: }
238:
239: // *********************************************************************************
240: // *********************************************************************************
241: // *********************************************************************************
242: public static Class getReferenceType(Class clazz, String name)
243: throws Exception {
244: Method m = getGetter(clazz, name);
245: if (m == null) {
246: throw new Exception("reference getter not found: '" + name
247: + "' in " + clazz.getName() + " use annotation "
248: + ZGetter.class.getSimpleName());
249: }
250: return m.getReturnType();
251: }
252:
253: private static Object invoke(Method method, Object obj,
254: Object... value) throws Exception {
255: if (log.isDebugEnabled()) {
256: log.debug("invoke " + method);
257: }
258: Object ret = method.invoke(obj, value);
259: return ret;
260: }
261:
262: public static <T> T newInstance(Class<T> clazz) throws Exception {
263: if (log.isDebugEnabled()) {
264: log.debug("new " + clazz.getName());
265: }
266: T ret = clazz.newInstance();
267: return ret;
268: }
269:
270: // ***************************************************************************************
271: // ***************************************************************************************
272: // ***************************************************************************************
273:
274: public static String computePrefixName(String prefix, String name) {
275: if (name.length() == 0) {
276: return prefix;
277: }
278: return prefix + Character.toUpperCase(name.charAt(0))
279: + name.substring(1);
280: }
281:
282: public static Method getGetter(Class clazz, String name)
283: throws Exception {
284: String getterName = computePrefixName("get", name);
285: Method ret = null;
286: Method[] methods = clazz.getMethods();
287: for (Method m : methods) {
288: if (m.isAnnotationPresent(ZGetter.class)) {
289: ZGetter ann = m.getAnnotation(ZGetter.class);
290: if (name.equals(ann.value())) {
291: return m;
292: }
293: } else if (m.getName().equals(getterName)) {
294: ret = m;
295: }
296: }
297:
298: return ret;
299: }
300:
301: public static Method getSetter(Class clazz, String name)
302: throws Exception {
303: String setterName = computePrefixName("set", name);
304: Method ret = null;
305: Method[] methods = clazz.getMethods();
306: for (Method m : methods) {
307: if (m.isAnnotationPresent(ZSetter.class)) {
308: ZSetter ann = m.getAnnotation(ZSetter.class);
309: if (name.equals(ann.value())) {
310: return m;
311: }
312: } else if (ZProperty.class.isAssignableFrom(m
313: .getReturnType())) {
314: ZGetter ann = m.getAnnotation(ZGetter.class);
315: if (ann != null && name.equals(ann.value())) {
316: return m;
317: }
318: } else if (m.getName().equals(setterName)) {
319: ret = m;
320: }
321: }
322: return ret;
323: }
324:
325: public static Method getBefore(Class clazz, String name)
326: throws Exception {
327: String methodName = computePrefixName("before", name);
328: Method ret = null;
329: Method[] methods = clazz.getMethods();
330: for (Method m : methods) {
331: if (m.isAnnotationPresent(ZBefore.class)) {
332: ZBefore ann = m.getAnnotation(ZBefore.class);
333: if (name.equals(ann.value())) {
334: return m;
335: }
336: } else if (m.getName().equals(methodName)) {
337: ret = m;
338: }
339: }
340: return ret;
341: }
342:
343: public static Method getAfter(Class clazz, String name)
344: throws Exception {
345: String methodName = computePrefixName("after", name);
346: Method ret = null;
347: Method[] methods = clazz.getMethods();
348: for (Method m : methods) {
349: if (m.isAnnotationPresent(ZAfter.class)) {
350: ZAfter ann = m.getAnnotation(ZAfter.class);
351: if (name.equals(ann.value())) {
352: return m;
353: }
354: } else if (m.getName().equals(methodName)) {
355: ret = m;
356: }
357: }
358: return ret;
359: }
360:
361: public static Method getInit(Class clazz, String name) {
362: String methodName = computePrefixName("init", name);
363: Method ret = null;
364: Method[] methods = clazz.getMethods();
365: for (Method m : methods) {
366: if (m.isAnnotationPresent(ZInit.class)) {
367: ZInit ann = m.getAnnotation(ZInit.class);
368: if (name.equals(ann.value())) {
369: return m;
370: }
371: } else if (m.getName().equals(methodName)) {
372: ret = m;
373: }
374: }
375: return ret;
376: }
377: }
|