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: RmiHandler.java,v 1.1 2002/11/11 22:19:48 mikehenderson Exp $
26   package com.mjh.switchrmi;
27   
28   import com.mjh.switchrmi.jndi.*;
29   
30   import java.lang.reflect.*;
31   
32   import java.util.*;
33   
34   import javax.naming.*;
35   
36   import org.apache.log4j.Logger;
37   
38   public class RmiHandler
39   {
40       private static HashMap applicationScope = new HashMap();
41       private static final Logger log = 
42               Logger.getLogger(RmiHandler.class.getName());
43       private RmiRequest request;
44       private RmiResponse response;
45   
46       public RmiHandler()
47       {
48       }
49   
50       public Object clientInvoke(Method method, Object[] args, RmiContext context)
51                           throws Exception
52       {
53           Object result = null;
54           RmiProtocol protocol = context.getProtocol();
55   
56           if (log.isDebugEnabled())
57           {
58               log.debug("protocol = " + protocol);
59           }
60   
61           RmiTransport transport = context.getTransport();
62   
63           if (log.isDebugEnabled())
64           {
65               log.debug("transport = " + transport);
66           }
67   
68           request = protocol.createRequest(method, args, context);
69           protocol.writeRequest(request, context);
70   
71           if (log.isDebugEnabled())
72           {
73               log.debug("transport = " + transport);
74           }
75   
76           transport.send(context);
77           transport.recv(context);
78           response = protocol.readResponse(context);
79           result = response.getObject();
80   
81           if (result instanceof Throwable)
82           {
83               throw (Exception) result;
84           }
85   
86           return result;
87       }
88   
89       private Object findTarget(RmiContext context, RmiSessionScopeAccess session)
90                          throws Exception
91       {
92           Object result = null;
93           Context ctx = (Context) context.lookup("/switchrmi/service/object");
94   
95           if (log.isDebugEnabled())
96           {
97               log.debug("ctx = " + ctx);
98           }
99   
100          if (ctx != null)
101          {
102              String name = context.getObjectName();
103  
104              if (log.isDebugEnabled())
105              {
106                  log.debug("name = " + name);
107              }
108  
109              ObjectReferenceable ref = 
110                      (ObjectReferenceable) ctx.getEnvironment().get(name);
111  
112              if (log.isDebugEnabled())
113              {
114                  log.debug("ref = " + ref);
115              }
116  
117              if (ref != null)
118              {
119                  String scope = ref.getScope();
120  
121                  if (scope.equals(RmiScope.APPLICATION))
122                  {
123                      result = applicationScope.get(name);
124  
125                      if (result == null)
126                      {
127                          result = ctx.lookup(name);
128                          applicationScope.put(name, result);
129                      }
130                  }
131                  else if (scope.equals(RmiScope.SESSION))
132                  {
133                      result = session.get(name);
134  
135                      if (result == null)
136                      {
137                          result = ctx.lookup(name);
138                          session.put(name, result);
139                      }
140                  }
141                  else
142                  {
143                      result = ctx.lookup(name);
144                  }
145  
146                  if (log.isDebugEnabled())
147                  {
148                      log.debug("result = " + result);
149                  }
150              }
151          }
152  
153          return result;
154      }
155  
156      public void serviceInvoke(RmiContext context, RmiSessionScopeAccess session)
157      {
158          RmiProtocol protocol = null;
159          RmiTransport transport = null;
160  
161          try
162          {
163              Object target = findTarget(context, session);
164  
165              if (log.isDebugEnabled())
166              {
167                  log.debug("target = " + target);
168              }
169  
170              context.setTarget(target);
171              protocol = context.getProtocol();
172              transport = context.getTransport();
173  
174              if (log.isDebugEnabled())
175              {
176                  log.debug("protocol  = " + protocol);
177                  log.debug("transport = " + transport);
178              }
179  
180              transport.recv(context);
181              request = protocol.readRequest(context);
182  
183              if (log.isDebugEnabled())
184              {
185                  log.debug("request = " + request);
186              }
187  
188              Method method = request.getMethod();
189  
190              if (log.isDebugEnabled())
191              {
192                  log.debug("method.getName() = " + method.getName());
193                  log.debug("method.getDeclaringClass().getName() = "
194                            + method.getDeclaringClass().getName());
195                  log.debug("target = " + target.getClass().getName());
196              }
197  
198              Object result = method.invoke(target, request.getArguments());
199  
200              response = protocol.createResponse(request, result, context);
201          }
202          catch (InvocationTargetException ex)
203          {
204              response = protocol.createResponse(request, ex.getTargetException(), 
205                                                 context);
206          }
207          catch (UndeclaredThrowableException ex)
208          {
209              response = protocol.createResponse(request, 
210                                                 ex.getUndeclaredThrowable(), 
211                                                 context);
212          }
213          catch (Exception ex)
214          {
215              if (log.isDebugEnabled())
216              {
217                  ex.printStackTrace();
218              }
219  
220              response = protocol.createResponse(request, ex, context);
221          }
222          finally
223          {
224              try
225              {
226                  protocol.writeResponse(response, context);
227                  transport.send(context);
228              }
229              catch (Exception ex)
230              {
231                  log.debug("Unable to send a response", ex);
232              }
233          }
234      }
235  
236      public void reset()
237      {
238          response = null;
239          request = null;
240      }
241  
242      public void handleFault(Exception ex, RmiContext context)
243                       throws Exception
244      {
245          if (response == null)
246          {
247              RmiProtocol protocol = context.getProtocol();
248  
249              response = protocol.createResponse(request, ex, context);
250              protocol.writeResponse(response, context);
251          }
252      }
253  }