001 /*
002 * hammurapi-rules @mesopotamia.version@
003 * Hammurapi rules engine.
004 * Copyright (C) 2005 Hammurapi Group
005 *
006 * This program is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 2 of the License, or (at your option) any later version.
010 *
011 * This program is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public
017 * License along with this library; if not, write to the Free Software
018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019 *
020 * URL: http://http://www.hammurapi.biz
021 * e-Mail: support@hammurapi.biz
022 */
023 package biz.hammurapi.dispatch;
024
025 import java.lang.reflect.Method;
026 import java.util.ArrayList;
027 import java.util.Collection;
028 import java.util.Collections;
029 import java.util.List;
030
031 /**
032 * This class introspects an object passed to the constructor and creates
033 * invocation handlers for methods with one argument and the name provided in
034 * the constructor.
035 * Invocation handler would not invoke target method with incompatible argument.
036 * @author Pavel Vlasov
037 * @revision $Revision$
038 */
039 public class IntrospectingInvocationTarget implements InvocationTarget {
040
041 List handlers=new ArrayList();
042
043 /**
044 * Introspects the target and creates an array of invocation handlers.
045 * @param targetInstance Target instance
046 * @param methodName Method name
047 * @param parameterType Invocation handlers shall accept arguments of this type. Can be null.
048 */
049 public IntrospectingInvocationTarget(final Object targetInstance, final String methodName, Class parameterType) {
050 super();
051
052
053 Method[] methods=targetInstance.getClass().getMethods();
054 for (int i=0; i<methods.length; i++) {
055 if (methods[i].getParameterTypes().length == 1) {
056 if (methodName.equals(methods[i].getName())) {
057 final Method method=methods[i];
058 final Class actualParameterType = method.getParameterTypes()[0];
059
060 // Make sure that target method will accept parameterType arguments
061 if ((parameterType==null || actualParameterType.isAssignableFrom(parameterType))) {
062 handlers.add(
063 new InvocationHandler() {
064
065 public void invoke(Object arg, ResultConsumer resultConsumer) throws Throwable {
066 // Invoke only with compatible parameters.
067 if (actualParameterType.isInstance(arg)) {
068 Object ret=method.invoke(targetInstance, new Object[] {arg});
069 if (ret!=null && resultConsumer!=null) {
070 resultConsumer.consume(ret);
071 }
072 }
073 }
074
075 public Class getParameterType() {
076 return actualParameterType;
077 }
078
079 public String toString() {
080 return "["+methodName+" handler] Target method: "+method;
081 }
082
083 });
084 }
085 }
086 }
087 }
088
089 }
090
091 public Collection getInvocationHandlers() {
092 return Collections.unmodifiableCollection(handlers);
093 }
094
095 }