1    //
2    // SwitchRMI  Framework
3    // Copyright (c) 2000-2002 by Michael J. Henderson & Associates.
4    //
5    // Michael Henderson
6    // http://switchrmi.sf.net
7    // mailto:mikehenderson@dunelm.org.uk
8    //
9    // This library is free software.
10   //
11   // You may redistribute it and/or modify it under the terms of the GNU
12   // Lesser General Public License as published by the Free Software Foundation.
13   //
14   // Version 2.1 of the license should be included with this distribution in
15   // the file LICENSE, as well as License.html. If the license is not
16   // included with this distribution, you may find a copy at the FSF web
17   // site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
18   // Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.
19   //
20   // This library is distributed in the hope that it will be useful,
21   // but WITHOUT ANY WARRANTY; without even the implied waranty of
22   // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23   // Lesser General Public License for more details.
24   //
25   // $Id: RmiRequestImpl.java,v 1.1 2002/11/11 22:19:48 mikehenderson Exp $
26   package com.mjh.switchrmi;
27   
28   import java.io.Serializable;
29   
30   import java.lang.reflect.Method;
31   
32   import java.util.*;
33   
34   import org.apache.log4j.*;
35   
36   public class RmiRequestImpl implements Serializable, RmiRequest
37   {
38       private static final Logger log = 
39               Logger.getLogger(RmiRequestImpl.class.getName());
40       private static HashMap primitives = new HashMap();
41   
42       static
43       {
44           primitives.put("char", char.class);
45           primitives.put("boolean", boolean.class);
46           primitives.put("byte", byte.class);
47           primitives.put("short", short.class);
48           primitives.put("int", int.class);
49           primitives.put("long", long.class);
50           primitives.put("float", float.class);
51           primitives.put("double", double.class);
52       }
53   
54       /**
55        *
56        *
57        */
58       private static HashMap signatures = new HashMap();
59       private String encodedMethodSignature;
60       private Object[] args;
61       public transient String interfaceName;
62       private transient String methodName;
63       private transient Class[] argumentTypes;
64       private transient String returnType;
65       private transient String[] stringArgumentTypes;
66   
67       public RmiRequestImpl()
68       {
69           interfaceName = "java.lang.Object";
70       }
71   
72       public RmiRequestImpl(Method method, Object[] mArgs)
73       {
74           encodedMethodSignature = encodeSignature(method);
75           args = mArgs;
76       }
77   
78       /**
79        *
80        *
81        */
82       private static synchronized String lookupMethodSignature(Method m)
83       {
84           return (String) signatures.get(m);
85       }
86   
87       /**
88        *
89        *
90        */
91       private static synchronized void storeMethodSignature(Method m, 
92                                                             String signature)
93       {
94           signatures.put(m, signature);
95       }
96   
97       /**
98        *
99        *
100       */
101      public void setEncodedMethodSignature(String encoded)
102      {
103          encodedMethodSignature = encoded;
104          decodeSignature(encoded);
105      }
106  
107      public String getEncodedMethodSignature()
108      {
109          return encodedMethodSignature;
110      }
111  
112      public void setArguments(Object[] args)
113      {
114          this.args = args;
115      }
116  
117      public Object[] getArguments()
118      {
119          return args;
120      }
121  
122      public String getInterfaceName()
123      {
124          if (interfaceName == null)
125          {
126              decodeSignature();
127          }
128  
129          return interfaceName;
130      }
131  
132      public String getReturnType()
133      {
134          if (returnType == null)
135          {
136              decodeSignature();
137          }
138  
139          return returnType;
140      }
141  
142      public void setReturnType(String string)
143      {
144          if (methodName == null)
145          {
146              decodeSignature();
147          }
148  
149          returnType = string;
150      }
151  
152      public String getMethodName()
153      {
154          if (methodName == null)
155          {
156              decodeSignature();
157          }
158  
159          return methodName;
160      }
161  
162      public Class[] getArgumentTypes()
163      {
164          if (argumentTypes == null)
165          {
166              decodeSignature();
167          }
168  
169          return argumentTypes;
170      }
171  
172      public String[] getStringArgumentTypes()
173      {
174          if (stringArgumentTypes == null)
175          {
176              decodeSignature();
177          }
178  
179          return stringArgumentTypes;
180      }
181  
182      public Method getMethod()
183      {
184          Method method = null;
185  
186          try
187          {
188              log.debug("interfaceName = " + getInterfaceName());
189  
190              Class interfaze = Class.forName(getInterfaceName());
191  
192              log.debug("interfaze = " + interfaze);
193              log.debug("methodName = " + getMethodName());
194              log.debug("argumentTypes = " + getArgumentTypes());
195              method = interfaze.getDeclaredMethod(getMethodName(), 
196                                                   getArgumentTypes());
197          }
198          catch (Exception ex)
199          {
200              ex.printStackTrace();
201              log.debug(ex);
202          }
203  
204          return method;
205      }
206  
207      private void debug(String msg)
208      {
209          log.debug(msg);
210      }
211  
212      /**
213       *
214       *
215       */
216      protected String encodeSignature(Method method)
217      {
218          String signature = lookupMethodSignature(method);
219  
220          if (signature == null)
221          {
222              Class declaringClass = method.getDeclaringClass();
223              Class returnType = method.getReturnType();
224              Class[] methodArgTypes = method.getParameterTypes();
225  
226              StringBuffer sb = new StringBuffer(declaringClass.getName());
227  
228              sb.append(":");
229              sb.append(returnType.getName());
230              sb.append(":");
231              sb.append(method.getName());
232              sb.append(":");
233  
234              int i = 0;
235  
236              if (methodArgTypes.length > 0)
237              {
238                  for (; i < (methodArgTypes.length - 1); i++)
239                  {
240                      sb.append(methodArgTypes[i].getName());
241                      sb.append(":");
242                  }
243  
244                  sb.append(methodArgTypes[i].getName());
245              }
246  
247              signature = sb.toString();
248              storeMethodSignature(method, signature);
249          }
250  
251          return signature;
252      }
253  
254      private void decodeSignature()
255      {
256          decodeSignature(encodedMethodSignature);
257      }
258  
259      /**
260       *
261       *
262       */
263      protected void decodeSignature(String encoded)
264      {
265          try
266          {
267              debug("decode: encoded = " + encoded);
268  
269              StringTokenizer tokenizer = new StringTokenizer(encoded, ":");
270  
271              interfaceName = tokenizer.nextToken();
272              debug("decode: interfaceName = " + interfaceName);
273              returnType = tokenizer.nextToken();
274              debug("decode: returnType = " + returnType);
275              methodName = tokenizer.nextToken();
276              debug("decode: methodName = " + methodName);
277  
278              if (tokenizer.hasMoreTokens())
279              {
280                  ArrayList list = new ArrayList();
281  
282                  while (tokenizer.hasMoreTokens())
283                  {
284                      list.add(tokenizer.nextToken());
285                  }
286  
287                  Object[] array = list.toArray();
288  
289                  stringArgumentTypes = new String[array.length];
290                  argumentTypes = new Class[array.length];
291  
292                  for (int i = 0; i < array.length; i++)
293                  {
294                      stringArgumentTypes[i] = (String) array[i];
295                      argumentTypes[i] = (Class) primitives.get(array[i]);
296  
297                      if (argumentTypes[i] == null)
298                      {
299                          argumentTypes[i] = Class.forName(stringArgumentTypes[i]);
300                      }
301  
302                      debug("decode: argumentTypes[i] = " + argumentTypes[i]);
303                  }
304              }
305          }
306          catch (Exception ex)
307          {
308              log.debug("Exception", ex);
309          }
310      }
311  }