KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gcc > rmi > iiop > server > MessageHandler


1 /*
2  * Copyright 2004 The Apache Software Foundation or its licensors, as
3  * applicable.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14  * implied.
15  *
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */

19 package gcc.rmi.iiop.server;
20
21 import gcc.*;
22 import gcc.adapter.Adapter;
23 import gcc.adapter.AdapterManager;
24 import gcc.naming.NameService;
25 import gcc.org.omg.IOP.*;
26 import gcc.org.omg.GIOP.*;
27 import gcc.properties.*;
28 import gcc.rmi.iiop.*;
29 import gcc.util.*;
30
31 import java.net.*;
32
33 public class MessageHandler extends Thread
34 {
35     public static MessageHandler getInstance(ListenerInfo listenerInfo, Socket socket)
36     {
37         MessageHandler object = new MessageHandler();
38         object.init(listenerInfo, socket);
39         return object;
40     }
41
42     // -----------------------------------------------------------------------
43
// properties
44
// -----------------------------------------------------------------------
45

46
47     public static final BooleanProperty simpleIDLProperty =
48         new BooleanProperty(SystemProperties.class, "gcc.simpleIDL");
49
50     public static BooleanProperty writeSystemExceptionStackTraceProperty =
51         new BooleanProperty(SystemProperties.class, "gcc.rmi.iiop.writeSystemExceptionStackTrace")
52         .defaultValue(true);
53
54     // -----------------------------------------------------------------------
55
// private data
56
// -----------------------------------------------------------------------
57

58     private static final boolean SIMPLE_IDL = simpleIDLProperty.getBoolean();
59
60     private static boolean _writeSystemExceptionStackTrace = writeSystemExceptionStackTraceProperty.getBoolean();
61
62     private static RequestHandler[] _handlers = new RequestHandler[128];
63
64     private NameService _nameService;
65     private ListenerInfo _listenerInfo;
66     private java.net.Socket _socket;
67     private java.io.InputStream _socketIn;
68     private java.io.OutputStream _socketOut;
69     private String _clientHostName;
70     private String _clientHostAddress;
71     private String _clientInfo;
72     private gcc.rmi.iiop.ObjectInputStream _objectInput;
73     private gcc.rmi.iiop.ObjectOutputStream _objectOutput;
74     private gcc.rmi.iiop.ObjectInputStream _simpleInput;
75     private gcc.rmi.iiop.ObjectOutputStream _simpleOutput;
76
77     // -----------------------------------------------------------------------
78
// public methods
79
// -----------------------------------------------------------------------
80

81     public static void registerHandler(char keyType, RequestHandler handler)
82     {
83         _handlers[keyType] = handler;
84     }
85
86     public void run()
87     {
88         ThreadContext.setDefaultRmiHost(_listenerInfo.host);
89         ThreadContext.setDefaultRmiPort(_listenerInfo.port);
90         boolean firstMessage = true;
91         CdrInputStream input = CdrInputStream.getInstance();
92         CdrOutputStream output = CdrOutputStream.getInstance();
93         CdrOutputStream results = CdrOutputStream.getInstance();
94         for (; ;)
95         {
96             boolean sendResponse = true;
97             GiopMessage inputMessage;
98             try
99             {
100                 inputMessage = input.receive_message(_socketIn, _clientInfo);
101                 firstMessage = false;
102             }
103             catch (BadMagicException ex)
104             {
105                 if (firstMessage)
106                 {
107                     warnBadMagic(_clientInfo, ex);
108                 }
109                 else
110                 {
111                     warnBadMagicBadSize(_clientInfo, ex);
112                 }
113                 closeSocket();
114                 return;
115             }
116             catch (UnsupportedProtocolVersionException ex)
117             {
118                 warnGiopVersion(_clientInfo, ex);
119                 closeSocket();
120                 return;
121             }
122             catch (Exception ex)
123             {
124                 if (input.getOffset() > 0)
125                 {
126                     ex.printStackTrace();
127                     warnReceiveFailed(_clientInfo, ex);
128                 }
129                 // Otherwise client shutdown was not in the middle of a
130
// request, i.e. probably 'normal' and unworthy of a
131
// log message.
132
closeSocket();
133                 return;
134             }
135             output.setGiopVersion(input.getGiopVersion());
136             switch (inputMessage.type)
137             {
138                 case MsgType_1_1._Request:
139                     processRequest(input, output, results, inputMessage.request);
140                     if ((inputMessage.request.response_flags & 1) == 0)
141                     {
142                         sendResponse = false; // oneway request
143
}
144                     break;
145                 case MsgType_1_1._LocateRequest:
146                     processLocateRequest(output, inputMessage.locateRequest);
147                     break;
148                 default:
149                     throw new SystemException("TODO: message type = " + inputMessage.type);
150             }
151             if (sendResponse)
152             {
153                 try
154                 {
155                     output.send_message(_socketOut, _clientInfo);
156                 }
157                 catch (Exception ex)
158                 {
159                     warnSendFailed(_clientInfo, ex);
160                     closeSocket();
161                     return;
162                 }
163             }
164             input.reset();
165             output.reset();
166             results.reset();
167         }
168     }
169
170     // -----------------------------------------------------------------------
171
// protected methods
172
// -----------------------------------------------------------------------
173

174     protected void init(ListenerInfo listenerInfo, Socket socket)
175     {
176         setDaemon(true);
177         _nameService = NameService.getInstance();
178         _listenerInfo = listenerInfo;
179         _socket = socket;
180         try
181         {
182             _socketIn = _socket.getInputStream();
183             _socketOut = _socket.getOutputStream();
184             InetAddress addr = _socket.getInetAddress();
185             _clientHostName = addr.getHostName();
186             _clientHostAddress = addr.getHostAddress();
187             _clientInfo = _clientHostName;
188             if (!_clientHostAddress.equals(_clientHostName))
189             {
190                 _clientInfo += " (" + _clientHostAddress + ")";
191             }
192         }
193         catch (Throwable ex)
194         {
195             closeSocket();
196             throw ExceptionUtil.rethrow(ex);
197         }
198     }
199
200     protected void closeSocket()
201     {
202         try
203         {
204             if (_socketIn != null)
205             {
206                 _socketIn.close();
207             }
208         }
209         catch (Exception ignore)
210         {
211         }
212         try
213         {
214             if (_socketOut != null)
215             {
216                 _socketOut.close();
217             }
218         }
219         catch (Exception ignore)
220         {
221         }
222         try
223         {
224             _socket.close();
225         }
226         catch (Exception ignore)
227         {
228         }
229     }
230
231     protected byte[] getObjectKey(TargetAddress target)
232     {
233         switch (target.discriminator())
234         {
235             case KeyAddr.value:
236                 return target.object_key();
237             case ProfileAddr.value:
238             case ReferenceAddr.value:
239                 throw new SystemException("TODO");
240             default:
241                 throw new IllegalArgumentException("target discriminator = " + target.discriminator());
242         }
243     }
244
245     protected void processRequest(CdrInputStream parameters, CdrOutputStream output, CdrOutputStream results, RequestHeader_1_2 request)
246     {
247         byte[] objectKey = getObjectKey(request.target);
248         int keyLength = objectKey.length;
249         int keyType = keyLength == 0 ? 0 : objectKey[0];
250         if (keyType >= 'A' && keyType <= 'Z')
251         {
252             RequestHandler handler = _handlers[keyType];
253             if (handler != null)
254             {
255                 handler.processRequest(objectKey, request.operation, parameters, output);
256                 return;
257             }
258         }
259
260         ReplyHeader_1_2 reply = new ReplyHeader_1_2();
261         reply.request_id = request.request_id;
262
263         gcc.rmi.iiop.ObjectInputStream objectIn;
264         gcc.rmi.iiop.ObjectOutputStream objectOut;
265
266         if (SIMPLE_IDL || keyType == 'N' || keyType == 'J')
267         {
268             // Name Service and JMS use simple IDL interoperability.
269
objectIn = gcc.rmi.iiop.SimpleObjectInputStream.getInstance(parameters);
270             objectOut = gcc.rmi.iiop.SimpleObjectOutputStream.getInstance(results);
271         }
272         else
273         {
274             // Otherwise use RMI-IIOP interoperability.
275
objectIn = gcc.rmi.iiop.ObjectInputStream.getInstance(parameters);
276             objectOut = gcc.rmi.iiop.ObjectOutputStream.getInstance(results);
277         }
278
279         try
280         {
281             String objectName = null;
282             for (int colonPos = 0; colonPos < keyLength; colonPos++)
283             {
284                 if (objectKey[colonPos] == ':')
285                 {
286                     objectName = UTF8.toString(objectKey, 0, colonPos);
287                     int newKeyLength = keyLength - colonPos - 1;
288                     byte[] newObjectKey = new byte[newKeyLength];
289                     System.arraycopy(objectKey, colonPos + 1, newObjectKey, 0, newKeyLength);
290                     objectKey = newObjectKey;
291                     break;
292                 }
293             }
294
295             if (objectName == null)
296             {
297                 objectName = UTF8.toString(objectKey);
298             }
299
300             /*
301             if (objectName.startsWith("EJB~"))
302             {
303                 // Compact encoding of component class names,
304                 // saves 11 bytes per request.
305                 objectName = "ejb.components." + objectName.substring(4);
306             }
307             */

308
309             processServiceContext(request);
310
311             /*
312             Object object;
313             try
314             {
315                 object = null; //_nameService.lookup(objectName);
316             }
317             catch (javax.naming.NameNotFoundException notFound)
318             {
319                 warnLookupFailed(_clientInfo, notFound);
320                 throw new org.omg.CORBA.OBJECT_NOT_EXIST(objectName);
321             }
322
323             if (object instanceof RemoteInterface)
324             {
325                 RemoteInterface skeleton = ((RemoteInterface)object).$getSkeleton();
326                 skeleton.$invoke(request.operation, objectKey, objectIn, objectOut);
327                 if (objectOut.hasException())
328                 {
329                     reply.reply_status = ReplyStatusType_1_2.USER_EXCEPTION;
330                 }
331                 else
332                 {
333                     reply.reply_status = ReplyStatusType_1_2.NO_EXCEPTION;
334                 }
335                 output.write_reply(reply, results);
336             }
337             else
338             {
339                 warnInvokeFailedNoRemoteInterface(_clientInfo, object, object.getClass());
340                 throw new org.omg.CORBA.OBJECT_NOT_EXIST(objectName);
341             }
342             */

343
344             Object object;
345             try
346             {
347                 object = _nameService.lookup(objectName);
348             }
349             catch (javax.naming.NameNotFoundException notFound)
350             {
351                 object = AdapterManager.getInstance().getAdapter( objectName );
352
353                 if (object == null)
354                 {
355                     warnLookupFailed(_clientInfo, notFound);
356                     throw new org.omg.CORBA.OBJECT_NOT_EXIST(objectName);
357                 }
358             }
359
360 // Adapter a = AdapterManager.getInstance().getAdapter(objectName);
361
// if (a != null)
362
if (object != null && object instanceof Adapter)
363             {
364                 Adapter a = (Adapter)object;
365                 //RemoteInterface skeleton = a.getRemoteInterface();
366
a.invoke(request.operation, objectKey, objectIn, objectOut);
367
368                 if (objectOut.hasException())
369                 {
370                     reply.reply_status = ReplyStatusType_1_2.USER_EXCEPTION;
371                 }
372                 else
373                 {
374                     reply.reply_status = ReplyStatusType_1_2.NO_EXCEPTION;
375                 }
376                 output.write_reply(reply, results);
377             }
378             else
379             {
380                 throw new org.omg.CORBA.OBJECT_NOT_EXIST(objectName);
381             }
382         }
383         catch (Exception ex)
384         {
385             warnSystemException(_clientInfo, ex);
386             results = CdrOutputStream.getInstance(); // in case we already wrote to it
387
results.write_SystemException(ex, _writeSystemExceptionStackTrace);
388             reply.reply_status = ReplyStatusType_1_2.SYSTEM_EXCEPTION;
389             output.write_reply(reply, results);
390         }
391     }
392
393     protected void processLocateRequest(CdrOutputStream output, LocateRequestHeader_1_2 request)
394     {
395         // Fake LocateReply, pretend we host any object.
396
// Since we never move objects, this is sufficient.
397
LocateReplyHeader_1_2 reply = new LocateReplyHeader_1_2();
398         reply.request_id = request.request_id;
399         reply.locate_status = LocateStatusType_1_2.OBJECT_HERE;
400         output.write_reply(reply);
401     }
402
403     protected void processServiceContext(RequestHeader_1_2 request)
404     {
405         ServiceContext[] contextList = request.service_context;
406         int n = contextList.length;
407         String username = null;
408         String password = null;
409
410         for (int i = 0; i < n; i++)
411         {
412             ServiceContext context = contextList[i];
413             int tag = context.context_id;
414
415             /*
416             if (tag == SecurityInfo.TAG_USERNAME)
417             {
418                 username = SecurityInfo.decode(context.context_data);
419             }
420             else if (tag == SecurityInfo.TAG_PASSWORD)
421             {
422                 password = SecurityInfo.decode(context.context_data);
423             }
424             */

425             // Otherwise OK to ignore unknown tags.
426
}
427
428         // Default security info.
429
/*
430         if (username == null)
431         {
432             username = User.GUEST;
433         }
434         if (password == null)
435         {
436             password = "";
437         }
438
439         // Check if the password is correct.
440         User user = User.getInstance(username);
441         user.login(password); // may throw SecurityException
442         User.setCurrent(user);
443         SimpleSubject.setCurrent(new SimpleSubject(username, password));
444         */

445     }
446
447     // log methods
448

449     protected void warnBadMagic(String clientHost, Exception ex)
450     {
451         System.out.println("MH.warnBadMagic: clientHost: " + clientHost + ", ex = " + ex);
452     }
453
454     protected void warnBadMagicBadSize(String clientHost, Exception ex)
455     {
456         System.out.println("MH.warnBadMagicBadSize: clientHost: " + clientHost + ", ex = " + ex);
457     }
458
459     protected void warnGiopVersion(String clientHost, Exception ex)
460     {
461         System.out.println("MH.warnGiopVersion: clientHost: " + clientHost + ", ex = " + ex);
462     }
463
464     protected void warnInvokeFailedNoRemoteInterface(String clientHost, Object object, Class type)
465     {
466         System.out.println("MH.warnInvokeFailedNoRemoteInterface: clientHost: " + clientHost + ", object = " + object + ", type: " + type);
467     }
468
469     protected void warnLookupFailed(String clientHost, Exception ex)
470     {
471         System.out.println("MH.warnLookupFailed: clientHost: " + clientHost + ", ex = " + ex);
472     }
473
474     protected void warnReceiveFailed(String clientHost, Exception ex)
475     {
476         System.out.println("MH.warnReceiveFailed: clientHost: " + clientHost + ", ex = " + ex);
477     }
478
479     protected void warnSendFailed(String clientHost, Exception ex)
480     {
481         System.out.println("MH.warnSendFailed: clientHost: " + clientHost + ", ex = " + ex);
482     }
483
484     protected void warnSystemException(String clientHost, Exception ex)
485     {
486         System.out.println("MH.warnSystemException: clientHost: " + clientHost + ", ex = " + ex);
487     }
488
489 }
490
Popular Tags