View Javadoc

1   /*
2    * Copyright (c) 2005 Regents of the University of California (Regents). Created
3    * by TELS, Graduate School of Education, University of California at Berkeley.
4    *
5    * This software is distributed under the GNU Lesser General Public License, v2.
6    *
7    * Permission is hereby granted, without written agreement and without license
8    * or royalty fees, to use, copy, modify, and distribute this software and its
9    * documentation for any purpose, provided that the above copyright notice and
10   * the following two paragraphs appear in all copies of this software.
11   *
12   * REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
13   * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
14   * PURPOSE. THE SOFTWAREAND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
15   * HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
16   * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
17   *
18   * IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
19   * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
20   * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
21   * REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22   */
23  package net.sf.sail.common.beansupport;
24  
25  import java.lang.reflect.InvocationTargetException;
26  import java.lang.reflect.Method;
27  import java.util.ArrayList;
28  import java.util.HashMap;
29  import java.util.Iterator;
30  import java.util.List;
31  import java.util.Map;
32  import java.util.logging.Logger;
33  
34  @SuppressWarnings("unchecked")
35  public class DynamicObject
36  {
37  	/**
38  	 * Logger for this class
39  	 */
40  	private static final Logger logger = Logger.getLogger(DynamicObject.class
41  			.getName());
42  
43  	protected static final Object [] NO_ARGS = new Object[0];
44  	protected MethodTable methods = new MethodTable();
45  	protected Class theClass;
46  	protected Object instance;
47  	
48  	public DynamicObject()
49  	{
50  	}
51  	
52  	public Class getInstanceClass()
53  	{
54  		return theClass;
55  	}
56  	
57  	public void setInstanceClass(ClassLoader loader, String className)
58  	{
59  		try
60  		{
61  			theClass = loader.loadClass(className);
62  			instance = theClass.newInstance();
63  			methods.setInstance(instance);
64  		}
65  		catch (ClassNotFoundException e)
66  		{
67  			logger.severe("ClassLoader, String -  : exception: " + e); //$NON-NLS-1$
68  		}
69  		catch (InstantiationException e)
70  		{
71  			logger.severe("ClassLoader, String -  : exception: " + e); //$NON-NLS-1$
72  		}
73  		catch (IllegalAccessException e)
74  		{
75  			logger.severe("ClassLoader, String -  : exception: " + e); //$NON-NLS-1$
76  		}
77  	}
78  	
79  	public Object getInstance()
80  	{
81  		return instance;
82  	}
83  	
84  	public void setInstance(Object instance)
85  	{
86  		theClass = instance.getClass();
87  		this.instance  = instance;
88  		methods.setInstance(instance);
89  	}
90  	
91  	public Object invoke(String methodName, Object [] args)
92  	{
93  		Method method = methods.findMethod(methodName, args);
94  		return invoke(method, args);
95  	}
96  	
97  	public Object invoke(String methodName)
98  	{
99  		return invoke(methodName, NO_ARGS);
100 	}
101 	
102 	protected Object invoke(Method method, Object [] args)
103 	{
104 		try
105 		{
106 			method.invoke(instance, args);
107 		}
108 		catch (IllegalArgumentException e)
109 		{
110 			// TODO Auto-generated catch block
111 			logger.severe("Method, Object[] -  : exception: " + e); //$NON-NLS-1$
112 		}
113 		catch (IllegalAccessException e)
114 		{
115 			// TODO Auto-generated catch block
116 			logger.severe("Method, Object[] -  : exception: " + e); //$NON-NLS-1$
117 		}
118 		catch (InvocationTargetException e)
119 		{
120 			// TODO Auto-generated catch block
121 			logger.severe("Method, Object[] -  : exception: " + e); //$NON-NLS-1$
122 		}
123 		return null;
124 	}
125 	
126 	public class SignatureList
127 	{
128 		protected Map methods = new HashMap();
129 		protected List<Signature> signatureList = new ArrayList<Signature>();
130 		
131 		public SignatureList(Class instanceClass, String name)
132 		{
133 //			List allSigs = new Vector();
134 			Method [] methods = instanceClass.getMethods();
135 			for (Method element : methods) {
136 				if (element.getName().equals(name))
137 				{
138 					signatureList.add(new Signature(element));
139 				}
140 			}
141 		}
142 		
143 		protected Signature findSignature(Object [] args)
144 		{
145 			Iterator signatures = signatureList.iterator();
146 			while (signatures.hasNext())
147 			{
148 				Signature signature = (Signature) signatures.next();
149 				if (signature.isSignature(args))
150 				{
151 					return signature;
152 				}
153 			}
154 			return null;
155 		}
156 		
157 		public Method findMethod(Object [] args)
158 		{
159 			Signature signature = findSignature(args);
160 			if (signature != null)
161 				return signature.getMethod();
162 			return null;
163 		}
164 	}
165 	
166 	public class Signature
167 	{
168 		protected Method method;
169 		protected Class<? extends Object>[] types;
170 		
171 		public Signature(Method method)
172 		{
173 			this.method = method;
174 			types = method.getParameterTypes();
175 		}
176 		
177 		public Method getMethod()
178 		{
179 			return method;
180 		}
181 
182 		public boolean isSignature(Object [] args)
183 		{
184 			if (types.length == args.length)
185 			{
186 				for (int i = 0; i < types.length; i++)
187 				{
188 					final Class<? extends Object> sourceClass = args[i].getClass();
189 					final Class<? extends Object> targetClass = types[i];
190 					if (! targetClass.isAssignableFrom(sourceClass))
191 					{
192 						return false;
193 					}
194 				}
195 				return true;
196 			}
197 			return false;
198 		}
199 	}
200 	
201 	public class MethodTable
202 	{
203 		protected Map<String,SignatureList> table = new HashMap<String,SignatureList>();
204 		protected Object instance;
205 		protected Class instanceClass;
206 		
207 		public MethodTable()
208 		{
209 		}
210 		
211 		public void setInstance(Object instance)
212 		{
213 			if (this.instance != null)
214 			{
215 				table.clear();
216 				this.instance = null;
217 				instanceClass = null;
218 			}
219 			this.instance = instance;
220 			if (this.instance != null)
221 			{
222 				instanceClass = this.instance.getClass();
223 			}
224 		}
225 		
226 		public Method findMethod(String name, Object [] args)
227 		{
228 			if (instance != null)
229 			{
230 				SignatureList list = table.get(name);
231 				if (list == null)
232 				{
233 					list = new SignatureList(instanceClass, name);
234 					table.put(name, list);
235 				}
236 				return list.findMethod(args);
237 			}
238 			return null;
239 		}
240 	}
241 }