KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jacorb > poa > RequestProcessor


1 package org.jacorb.poa;
2
3 /*
4  * JacORB - a free Java ORB
5  *
6  * Copyright (C) 1997-2004 Gerald Brose.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the Free
20  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */

22
23 import org.jacorb.poa.except.*;
24
25 import org.jacorb.util.*;
26 import org.jacorb.orb.dsi.ServerRequest;
27 import org.jacorb.orb.SystemExceptionHelper;
28 import org.jacorb.orb.portableInterceptor.*;
29 import org.jacorb.orb.giop.ReplyOutputStream;
30
31 import java.util.*;
32
33 import org.apache.avalon.framework.configuration.*;
34 import org.apache.avalon.framework.logger.Logger;
35
36 import org.omg.PortableServer.Servant JavaDoc;
37 import org.omg.PortableServer.ServantManager JavaDoc;
38 import org.omg.PortableServer.ServantActivator JavaDoc;
39 import org.omg.PortableServer.ServantLocator JavaDoc;
40 import org.omg.PortableServer.DynamicImplementation JavaDoc;
41 import org.omg.PortableServer.ServantLocatorPackage.CookieHolder JavaDoc;
42
43 import org.omg.CORBA.CompletionStatus JavaDoc;
44 import org.omg.CORBA.portable.InvokeHandler JavaDoc;
45 import org.omg.GIOP.ReplyStatusType_1_2;
46 import org.omg.PortableInterceptor.*;
47 import org.omg.IOP.ServiceContext JavaDoc;
48
49 /**
50  * This thread performs the request processing, the actual method invocation and
51  * it returns the ServerRequest object to the ORB.
52  *
53  * @author Reimo Tiedemann, FU Berlin
54  * @version $Id: RequestProcessor.java,v 1.31 2004/12/11 22:31:34 andre.spiegel Exp $
55  */

56
57 public class RequestProcessor
58     extends Thread JavaDoc
59     implements InvocationContext, Configurable
60 {
61     private boolean start;
62     private boolean terminate;
63     private RPPoolManager poolManager;
64
65     private RequestController controller;
66     private ServerRequest request;
67     private Servant JavaDoc servant;
68     private ServantManager JavaDoc servantManager;
69     private CookieHolder JavaDoc cookieHolder;
70     
71     /**
72      * Whether to check for expiry of any ReplyEndTimePolicy. Normally,
73      * it is sufficient to check this on the client side, but the additional
74      * check on the server side can save the server and the network some work.
75      * It requires that the clocks of the client and server machine are
76      * synchronized, though.
77      */

78     private boolean checkReplyEndTime = false;
79
80     /** this processor's logger instance, obtained from the request controller */
81     private Logger logger;
82
83     private static Map specialOperations;
84     private static int count = 0;
85
86     static
87     {
88         specialOperations = new HashMap(50);
89         specialOperations.put("_is_a", "");
90         specialOperations.put("_interface", "");
91         specialOperations.put("_non_existent", "");
92
93         specialOperations.put("_get_policy", "");
94         specialOperations.put("_set_policy_overrides", "");
95     }
96
97     RequestProcessor (RPPoolManager _poolManager)
98     {
99         super ("RequestProcessor-" + (++count));
100         poolManager = _poolManager;
101     }
102
103     public void configure (Configuration configuration)
104         throws ConfigurationException
105     {
106         checkReplyEndTime = configuration.getAttributeAsBoolean
107         (
108           "jacorb.poa.check_reply_end_time", false
109         );
110     }
111
112     /**
113      * starts the request processor
114      */

115
116     synchronized void begin()
117     {
118         start = true;
119         notify();
120     }
121
122     /**
123      * terminates the request processor
124      */

125
126     synchronized void end()
127     {
128         terminate = true;
129         notify();
130     }
131
132     /**
133      * returns the oid associated current servant invocation
134      */

135
136     public byte[] getObjectId()
137     {
138         if (!start)
139             throw new POAInternalError("error: RequestProcessor not started (getObjectId)");
140         return request.objectId();
141     }
142
143     /**
144      * returns the orb that has received the request
145      */

146
147     public org.omg.CORBA.ORB JavaDoc getORB()
148     {
149         if (!start)
150             throw new POAInternalError("error: RequestProcessor not started (getORB)");
151         return controller.getORB();
152     }
153
154     /**
155      * returns the poa that has dispatched the request
156      */

157
158     public POA getPOA()
159     {
160         if (!start)
161             throw new POAInternalError("error: RequestProcessor not started (getPOA)");
162         return controller.getPOA();
163     }
164
165     /**
166      * returns the actual servant
167      */

168
169     public Servant JavaDoc getServant()
170     {
171         if (!start)
172             throw new POAInternalError("error: RequestProcessor not started (getServant)");
173         return servant;
174     }
175
176     /**
177      * initializes the request processor
178      */

179
180     void init(RequestController controller,
181               ServerRequest request,
182               Servant JavaDoc servant,
183               ServantManager JavaDoc servantManager)
184     {
185         this.controller = controller;
186         this.request = request;
187         this.servant = servant;
188         this.servantManager = servantManager;
189         cookieHolder = null;
190         logger = controller.getLogger();
191     }
192
193     private void clear()
194     {
195         controller = null;
196         request = null;
197         servant = null;
198         servantManager = null;
199         cookieHolder = null;
200     }
201
202
203     /**
204      * causes the aom to perform the incarnate call on a servant activator
205      */

206
207     private void invokeIncarnate()
208     {
209         if (logger.isDebugEnabled())
210         {
211             logger.debug("rid: " + request.requestId() +
212                          " opname: " + request.operation() +
213                          " invoke incarnate on servant activator");
214         }
215         try
216         {
217
218             servant = controller.getAOM().incarnate( request.objectId(),
219                                                      (ServantActivator JavaDoc) servantManager,
220                                                      controller.getPOA());
221             if (servant == null)
222             {
223                 if (logger.isWarnEnabled())
224                 {
225                     logger.warn("rid: " + request.requestId() +
226                                 " opname: " + request.operation() +
227                                 " incarnate: returns null");
228                 }
229
230                 request.setSystemException(new org.omg.CORBA.OBJ_ADAPTER JavaDoc());
231             }
232
233             controller.getORB().set_delegate(servant); // set the orb
234
}
235         catch (org.omg.CORBA.SystemException JavaDoc e)
236         {
237             if (logger.isWarnEnabled())
238             {
239                 logger.warn("rid: "+request.requestId() +
240                             " opname: " + request.operation() +
241                             " incarnate: system exception was thrown (" +
242                             e.toString() + ")");
243             }
244             request.setSystemException(e);
245         }
246         catch (org.omg.PortableServer.ForwardRequest JavaDoc e)
247         {
248             if (logger.isWarnEnabled())
249             {
250                 logger.warn("rid: " + request.requestId() +
251                             " opname: " + request.operation() +
252                             " incarnate: forward exception was thrown (" +
253                             e.getMessage() + ")");
254             }
255             request.setLocationForward(e);
256
257         }
258         catch (Throwable JavaDoc e)
259         {
260             /* not spec. */
261             if (logger.isErrorEnabled())
262             {
263                 logger.error("rid: " + request.requestId() +
264                              " opname: " + request.operation() +
265                              " incarnate: throwable was thrown (" +
266                              e.getClass().getName() + ")", e);
267             }
268             request.setSystemException(new org.omg.CORBA.OBJ_ADAPTER JavaDoc(e.getMessage()));
269         }
270     }
271
272
273     /**
274      * invokes the operation on servant,
275      */

276
277     private void invokeOperation()
278     {
279         try
280         {
281             if (servant instanceof org.omg.CORBA.portable.InvokeHandler JavaDoc)
282             {
283                 if (logger.isDebugEnabled())
284                 {
285                     logger.debug("rid: " + request.requestId() +
286                                  " opname: " + request.operation() +
287                                  " invokeOperation on servant (stream based)");
288                 }
289
290                 if( specialOperations.containsKey(request.operation()))
291                 {
292                     ((org.jacorb.orb.ServantDelegate)servant._get_delegate())._invoke(servant,
293                                                                                       request.operation(),
294                                                                                       request.getInputStream(),
295                                                                                       request);
296                 }
297                 else
298                 {
299                     ((InvokeHandler JavaDoc) servant)._invoke(request.operation(),
300                                                       request.getInputStream(),
301                                                       request);
302                 }
303
304             }
305             else if (servant instanceof org.omg.PortableServer.DynamicImplementation JavaDoc)
306             {
307                 if (logger.isDebugEnabled())
308                 {
309                     logger.debug("rid: " + request.requestId() +
310                                  " opname: " + request.operation() +
311                                  " invoke operation on servant (dsi based)");
312                 }
313                 if( specialOperations.containsKey(request.operation()) &&
314                     !(servant instanceof org.jacorb.orb.Forwarder) )
315                 {
316                     ((org.jacorb.orb.ServantDelegate)servant._get_delegate())
317                         ._invoke(servant,
318                                  request.operation(),
319                                  request.getInputStream(),
320                                  request);
321                 }
322                 else
323                 {
324                     ((DynamicImplementation JavaDoc) servant).invoke(request);
325                 }
326             }
327             else
328             {
329                 if (logger.isWarnEnabled())
330                 {
331                     logger.warn("rid: " + request.requestId() +
332                                 " opname: " + request.operation() +
333                                 " unknown servant type (neither stream nor dsi based)");
334                 }
335             }
336
337         }
338         catch (org.omg.CORBA.SystemException JavaDoc e)
339         {
340             if (logger.isInfoEnabled())
341             {
342                 logger.info("rid: " + request.requestId() +
343                             " opname: " + request.operation() +
344                             " invocation: system exception was thrown (" +
345                             e.toString() + ")");
346             }
347             request.setSystemException(e);
348         }
349         catch (Throwable JavaDoc e)
350         {
351             /* not spec. */
352             if (logger.isErrorEnabled())
353             {
354                 logger.error("rid: " + request.requestId() +
355                              " opname: " + request.operation() +
356                              " invocation: throwable was thrown (" +
357                              e.getClass().getName() + ")", e);
358             }
359             request.setSystemException (new org.omg.CORBA.UNKNOWN JavaDoc(e.toString()));
360         }
361     }
362
363
364     /**
365      * performs the postinvoke call on a servant locator
366      */

367
368     private void invokePostInvoke()
369     {
370         try
371         {
372             if (logger.isDebugEnabled())
373             {
374                 logger.debug("rid: " + request.requestId() +
375                              " opname: " + request.operation() +
376                              " invoke postinvoke on servant locator");
377             }
378
379             ((ServantLocator JavaDoc) servantManager).postinvoke(request.objectId(),
380                                                          controller.getPOA(),
381                                                          request.operation(),
382                                                          cookieHolder.value,
383                                                          servant);
384         }
385         catch (org.omg.CORBA.SystemException JavaDoc e)
386         {
387             if (logger.isInfoEnabled())
388             {
389                 logger.info("rid: " + request.requestId() +
390                             " opname: " + request.operation() +
391                             " postinvoke: system exception was thrown (" +
392                             e.getMessage()+")");
393             }
394             request.setSystemException(e);
395
396         }
397         catch (Throwable JavaDoc e)
398         {
399             /* not spec. */
400             if (logger.isWarnEnabled())
401             {
402                 logger.warn("rid: " + request.requestId() +
403                             " opname: " + request.operation() +
404                             " postinvoke: throwable was thrown" + e.getMessage());
405             }
406             request.setSystemException(new org.omg.CORBA.OBJ_ADAPTER JavaDoc());
407             /* which system exception I should raise? */
408         }
409     }
410
411
412     /**
413      * performs the preinvoke call on a servant locator
414      */

415
416     private void invokePreInvoke()
417     {
418         if (logger.isDebugEnabled())
419         {
420             logger.debug("rid: " + request.requestId() +
421                          " opname: " + request.operation() +
422                          " invoke preinvoke on servant locator");
423         }
424         try
425         {
426             cookieHolder = new CookieHolder JavaDoc();
427             servant = ((ServantLocator JavaDoc) servantManager).preinvoke(request.objectId(),
428                                                                   controller.getPOA(),
429                                                                   request.operation(),
430                                                                   cookieHolder);
431             if (servant == null)
432             {
433                 if (logger.isWarnEnabled())
434                 {
435                     logger.warn("rid: " + request.requestId() +
436                                 " opname: " + request.operation() +
437                                 " preinvoke: returns null");
438                 }
439                 request.setSystemException(new org.omg.CORBA.OBJ_ADAPTER JavaDoc());
440             }
441             controller.getORB().set_delegate( servant ); // set the orb
442

443         }
444         catch (org.omg.CORBA.SystemException JavaDoc e)
445         {
446             if (logger.isInfoEnabled())
447             {
448                 logger.info("rid: " + request.requestId() +
449                             " opname: " + request.operation() +
450                             " preinvoke: system exception was thrown (" +
451                             e.getMessage() +")");
452             }
453             request.setSystemException(e);
454
455         }
456         catch (org.omg.PortableServer.ForwardRequest JavaDoc e)
457         {
458             if (logger.isInfoEnabled())
459             {
460                 logger.info("rid: " + request.requestId() +
461                             " opname: " + request.operation() +
462                             " preinvoke: forward exception was thrown (" +
463                             e.getMessage() + ")");
464             }
465             request.setLocationForward(e);
466         }
467         catch (Throwable JavaDoc e)
468         {
469             /* not spec. */
470             if (logger.isWarnEnabled())
471             {
472                 logger.warn("rid: " + request.requestId() +
473                             " opname: " + request.operation() +
474                             " preinvoke: throwable was thrown, " +
475                             e.getMessage());
476             }
477             request.setSystemException(new org.omg.CORBA.OBJ_ADAPTER JavaDoc(e.getMessage()));
478             /* which system exception I should raise? */
479         }
480     }
481
482     boolean isActive()
483     {
484         return start;
485     }
486
487
488     /**
489      * the main request processing routine
490      */

491
492     private void process()
493     {
494         ServerRequestInfoImpl info = null;
495
496         if (controller.getORB().hasServerRequestInterceptors())
497         {
498             //RequestInfo attributes
499
info = new ServerRequestInfoImpl(controller.getORB(),
500                                              request,
501                                              servant);
502
503             InterceptorManager manager = controller.getORB().getInterceptorManager();
504             info.setCurrent (manager.getEmptyCurrent());
505
506             if(! invokeInterceptors( info,
507                                      ServerInterceptorIterator.
508                                      RECEIVE_REQUEST_SERVICE_CONTEXTS))
509             {
510                 //an interceptor bailed out, so don't continue request
511
//processing and return here. The service contexts for
512
//the result have to be set, of course.
513
ReplyOutputStream out = request.getReplyOutputStream();
514                 Enumeration ctx = info.getReplyServiceContexts();
515
516                 while( ctx.hasMoreElements() )
517                 {
518                     out.addServiceContext( (ServiceContext JavaDoc) ctx.nextElement() );
519                 }
520
521                 return;
522             }
523
524             manager.setTSCurrent(info.current());
525         }
526
527         // TODO: The exception replies below should also trigger interceptors.
528
// Requires some re-arranging of the entire method.
529
if (Time.hasPassed (request.getRequestEndTime()))
530         {
531             request.setSystemException
532                 (new org.omg.CORBA.TIMEOUT JavaDoc ("Request End Time exceeded",
533                                             0, CompletionStatus.COMPLETED_NO));
534             return;
535         }
536         if (checkReplyEndTime && Time.hasPassed (request.getReplyEndTime()))
537         {
538             request.setSystemException
539                 (new org.omg.CORBA.TIMEOUT JavaDoc ("Reply End Time exceeded",
540                                             0, CompletionStatus.COMPLETED_NO));
541             return;
542         }
543
544         Time.waitFor (request.getRequestStartTime());
545
546         if (servantManager != null)
547         {
548             if (servantManager instanceof org.omg.PortableServer.ServantActivator JavaDoc)
549                 invokeIncarnate();
550             else
551                 invokePreInvoke();
552         }
553
554         if (servant != null)
555         {
556             if (info != null)
557             {
558                 info.setServant(servant);
559
560                 if (servant instanceof org.omg.CORBA.portable.InvokeHandler JavaDoc)
561                 {
562                     if(! invokeInterceptors(info,
563                                             ServerInterceptorIterator.RECEIVE_REQUEST ))
564                     {
565                         //an interceptor bailed out, so don't continue
566
//request processing and return here. The
567
//service contexts for the result have to be
568
//set, of course.
569

570                         if( cookieHolder != null )
571                         {
572                             invokePostInvoke();
573                         }
574
575                         ReplyOutputStream out =
576                             request.getReplyOutputStream();
577                         Enumeration ctx =
578                             info.getReplyServiceContexts();
579
580                         while( ctx.hasMoreElements() )
581                         {
582                             out.addServiceContext( (ServiceContext JavaDoc) ctx.nextElement() );
583                         }
584
585                         return;
586                     }
587                 }
588                 else if (servant instanceof org.omg.PortableServer.DynamicImplementation JavaDoc)
589                     request.setServerRequestInfo(info);
590
591             }
592
593             invokeOperation();
594         }
595
596         // preinvoke and postinvoke are always called in pairs
597
// but what happens if the servant is null
598

599         if (cookieHolder != null)
600         {
601             invokePostInvoke();
602         }
603
604         if (checkReplyEndTime && Time.hasPassed (request.getReplyEndTime()))
605         {
606             request.setSystemException
607                 (new org.omg.CORBA.TIMEOUT JavaDoc ("Reply End Time exceeded after invocation",
608                                             0, CompletionStatus.COMPLETED_YES));
609         }
610
611         if (info != null)
612         {
613             InterceptorManager manager =
614                 controller.getORB().getInterceptorManager();
615             info.setCurrent (manager.getCurrent());
616
617             short op = 0;
618             switch(request.status().value())
619             {
620                 case ReplyStatusType_1_2._NO_EXCEPTION :
621                     op = ServerInterceptorIterator.SEND_REPLY;
622                     info.setReplyStatus (SUCCESSFUL.value);
623                     break;
624
625                 case ReplyStatusType_1_2._USER_EXCEPTION :
626                     info.setReplyStatus (USER_EXCEPTION.value);
627                     SystemExceptionHelper.insert(info.sending_exception,
628                                                  new org.omg.CORBA.UNKNOWN JavaDoc("Stream-based UserExceptions are not available!"));
629                     op = ServerInterceptorIterator.SEND_EXCEPTION;
630                     break;
631
632                 case ReplyStatusType_1_2._SYSTEM_EXCEPTION :
633                     info.setReplyStatus (SYSTEM_EXCEPTION.value);
634                     SystemExceptionHelper.insert(info.sending_exception,
635                                                  request.getSystemException());
636                     op = ServerInterceptorIterator.SEND_EXCEPTION;
637                     break;
638
639                 case ReplyStatusType_1_2._LOCATION_FORWARD :
640                     info.setReplyStatus (LOCATION_FORWARD.value);
641                     op = ServerInterceptorIterator.SEND_OTHER;
642                     break;
643             }
644
645             invokeInterceptors(info, op);
646
647             ReplyOutputStream out =
648                 request.get_out();
649             Enumeration ctx =
650                 info.getReplyServiceContexts();
651
652             while( ctx.hasMoreElements() )
653             {
654                 out.addServiceContext( (ServiceContext JavaDoc) ctx.nextElement() );
655             }
656
657             manager.removeTSCurrent();
658         }
659     }
660
661     private boolean invokeInterceptors( ServerRequestInfoImpl info,
662                                         short op )
663     {
664
665         ServerInterceptorIterator intercept_iter =
666             controller.getORB().getInterceptorManager().getServerIterator();
667
668         try
669         {
670             intercept_iter.iterate(info, op);
671         }
672         catch(org.omg.CORBA.UserException JavaDoc ue)
673         {
674             if (ue instanceof org.omg.PortableInterceptor.ForwardRequest JavaDoc)
675             {
676                 org.omg.PortableInterceptor.ForwardRequest JavaDoc fwd =
677                     (org.omg.PortableInterceptor.ForwardRequest JavaDoc) ue;
678
679                 request.setLocationForward( new org.omg.PortableServer.
680
JavaDoc                    ForwardRequest(fwd.forward) );
681             }
682             return false;
683
684         }
685         catch (org.omg.CORBA.SystemException JavaDoc _sys_ex)
686         {
687             request.setSystemException(_sys_ex);
688             return false;
689         }
690         return true;
691     }
692
693
694     /**
695      * the main loop for request processing
696      */

697
698     public void run()
699     {
700         while (!terminate)
701         {
702             synchronized (this)
703             {
704                 while (! start)
705                 {
706                     try
707                     {
708                         wait(); /* waits for the next task */
709                     }
710                     catch (InterruptedException JavaDoc e)
711                     {
712                     }
713                     
714                     if (terminate)
715                     {
716                         return;
717                     }
718                 }
719             }
720
721             if (logger.isDebugEnabled())
722             {
723                 logger.debug("rid: " + request.requestId() +
724                              " opname: " + request.operation() +
725                              " starts with request processing");
726             }
727
728             if (request.syncScope() == org.omg.Messaging.SYNC_WITH_SERVER.value)
729             {
730                 controller.returnResult (request);
731                 process();
732             }
733             else
734             {
735                 process();
736                 controller.returnResult (request);
737
738             }
739
740             // return the request to the request controller
741
if (logger.isDebugEnabled())
742             {
743                 logger.debug("rid: " + request.requestId() +
744                              " opname: " + request.operation() +
745                              " ends with request processing");
746             }
747
748             controller.finish (request);
749
750             start = false;
751             clear();
752
753             // give back the processor into the pool
754
poolManager.releaseProcessor(this);
755         }
756     }
757 }
758
Popular Tags