KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jacorb > orb > dsi > ServerRequest


1 package org.jacorb.orb.dsi;
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 java.util.*;
24
25 import org.apache.avalon.framework.logger.Logger;
26
27 import org.jacorb.orb.CDRInputStream;
28 import org.jacorb.orb.CDROutputStream;
29 import org.jacorb.orb.giop.*;
30 import org.jacorb.config.Configuration;
31 import org.jacorb.orb.portableInterceptor.ServerInterceptorIterator;
32 import org.jacorb.orb.portableInterceptor.ServerRequestInfoImpl;
33 import org.jacorb.poa.util.POAUtil;
34 import org.jacorb.util.Time;
35
36 import org.omg.CORBA.INTERNAL JavaDoc;
37 import org.omg.GIOP.ReplyStatusType_1_2;
38 import org.omg.IOP.INVOCATION_POLICIES;
39 import org.omg.IOP.ServiceContext JavaDoc;
40 import org.omg.Messaging.*;
41 import org.omg.TimeBase.UtcT;
42
43 /**
44  * @author Gerald Brose, FU Berlin
45  * @version $Id: ServerRequest.java,v 1.32 2004/11/18 23:25:37 andre.spiegel Exp $
46  */

47
48 public class ServerRequest
49     extends org.omg.CORBA.ServerRequest JavaDoc
50     implements org.omg.CORBA.portable.ResponseHandler JavaDoc
51 {
52     private RequestInputStream in;
53     private ReplyOutputStream out;
54     private GIOPConnection connection;
55
56     private UtcT requestStartTime = null,
57                  requestEndTime = null,
58                  replyEndTime = null;
59
60     /**
61      * <code>scopes</code> caches the scoped poa names.
62      */

63     private List scopes;
64
65     /** config property */
66     private boolean cachePoaNames;
67
68     private int status = ReplyStatusType_1_2._NO_EXCEPTION;
69     private byte[] oid;
70     private byte[] object_key;
71     private org.omg.CORBA.Object JavaDoc reference = null;
72     /**
73      * <code>rest_of_name</code> is target poa's name in relation to parent.
74      */

75     private String JavaDoc[] rest_of_name = null;
76
77     /* is this request stream or DSI-based ? */
78     private boolean stream_based;
79
80     private org.omg.CORBA.SystemException JavaDoc sys_ex;
81     private org.omg.PortableServer.ForwardRequest JavaDoc location_forward;
82     private org.omg.CORBA.Any JavaDoc ex;
83     private org.omg.CORBA.Any JavaDoc result;
84     private org.jacorb.orb.NVList args;
85
86     private org.jacorb.orb.ORB orb;
87
88     private boolean usePreconstructedReply = false; //for appligator
89

90     private ServerRequestInfoImpl info = null;
91
92     private Logger logger;
93
94
95     public ServerRequest( org.jacorb.orb.ORB orb,
96                           RequestInputStream in,
97                           GIOPConnection _connection )
98     {
99         this.orb = orb;
100         Configuration config = orb.getConfiguration();
101         this.logger = config.getNamedLogger("jacorb.org.giop");
102         this.cachePoaNames = config.getAttribute("jacorb.cachePoaNames","off").equals("on");
103
104         this.in = in;
105         connection = _connection;
106
107         getTimingPolicies();
108
109         object_key =
110             orb.mapObjectKey(org.jacorb.orb.ParsedIOR.extractObjectKey(in.req_hdr.target, orb));
111
112         oid = org.jacorb.poa.util.POAUtil.extractOID( object_key );
113     }
114
115     /*
116      * if this request could not be delivered directly to the correct
117      * POA because the POA's adapter activator could not be called
118      * when the parent POA was in holding state, the parent will queue
119      * the request and later return it to the adapter layer. In order
120      * to be able to find the right POA when trying to deliver again,
121      * we have to remember the target POA's name
122      */

123
124     public void setRemainingPOAName(String JavaDoc [] rest_of_name)
125     {
126         this.rest_of_name = rest_of_name;
127     }
128
129     /**
130      * <code>remainingPOAName</code> retrieves (if any) the target poa's
131      * name in relation to parent.
132      * @return a <code>String[]</code> value
133      */

134     public String JavaDoc[] remainingPOAName()
135     {
136         return rest_of_name;
137     }
138
139     public String JavaDoc operation()
140     {
141         return in.req_hdr.operation;
142     }
143
144     /**
145      * The resulting any must be used to create an input stream from
146      * which the result value can be read.
147      */

148
149     public org.omg.CORBA.Any JavaDoc result()
150     {
151         if( stream_based )
152         {
153             org.omg.CORBA.Any JavaDoc any = orb.create_any();
154
155             // create the output stream for the result
156

157             CDROutputStream _out = ((CDROutputStream)any.create_output_stream());
158
159             // get a copy of the content of this reply
160
byte[] result_buf = out.getBody();
161
162             // ... and insert it
163
_out.setBuffer( result_buf );
164             // important: set the _out buffer's position to the end of the contents!
165
_out.skip( result_buf.length );
166             return any;
167         }
168         return result;
169     }
170
171     public org.omg.CORBA.NVList JavaDoc arguments()
172     {
173         if( stream_based )
174             throw new RuntimeException JavaDoc("This ServerRequest is stream-based!");
175         return args;
176     }
177
178     public org.omg.CORBA.Any JavaDoc except()
179     {
180         if( stream_based )
181             throw new RuntimeException JavaDoc("This ServerRequest is stream-based!");
182         return ex;
183     }
184
185     public ReplyStatusType_1_2 status()
186     {
187         return ReplyStatusType_1_2.from_int( status );
188     }
189
190     public org.omg.CORBA.Context JavaDoc ctx()
191     {
192         return null;
193     }
194
195     public void arguments(org.omg.CORBA.NVList JavaDoc p)
196     {
197         args = (org.jacorb.orb.NVList)p;
198         // unmarshal
199

200         if( args != null )
201         {
202             in.mark(0);
203             for( java.util.Enumeration JavaDoc e = args.enumerate();
204                  e.hasMoreElements(); )
205             {
206                 org.omg.CORBA.NamedValue JavaDoc nv =
207                     (org.omg.CORBA.NamedValue JavaDoc)e.nextElement();
208
209                 if( nv.flags() != org.omg.CORBA.ARG_OUT.value )
210                 {
211                     // out parameters are not received
212
try
213                     {
214                         nv.value().read_value( in, nv.value().type() );
215                     }
216                     catch (Exception JavaDoc ex)
217                     {
218                         throw new org.omg.CORBA.MARSHAL JavaDoc("Couldn't unmarshal object of type "
219                                                         + nv.value().type() + " in ServerRequest.");
220                     }
221                 }
222             }
223             try
224             {
225                 in.reset();
226             }
227             catch (Exception JavaDoc ex)
228             {
229                 throw new org.omg.CORBA.UNKNOWN JavaDoc("Could not reset input stream");
230             }
231
232             if (info != null)
233             {
234                 //invoke interceptors
235
org.omg.Dynamic.Parameter JavaDoc[] params = new org.omg.Dynamic.Parameter JavaDoc[args.count()];
236                 for (int i = 0; i < params.length; i++)
237                 {
238                     try
239                     {
240                         org.omg.CORBA.NamedValue JavaDoc value = args.item(i);
241
242                         org.omg.CORBA.ParameterMode JavaDoc mode = null;
243                         if (value.flags() == org.omg.CORBA.ARG_IN.value)
244                             mode = org.omg.CORBA.ParameterMode.PARAM_IN;
245                         else if (value.flags() == org.omg.CORBA.ARG_OUT.value)
246                             mode = org.omg.CORBA.ParameterMode.PARAM_OUT;
247                         else if (value.flags() == org.omg.CORBA.ARG_INOUT.value)
248                             mode = org.omg.CORBA.ParameterMode.PARAM_INOUT;
249
250                         params[i] = new org.omg.Dynamic.Parameter JavaDoc(value.value(), mode);
251                     }
252                     catch (Exception JavaDoc e)
253                     {
254                         if (logger.isInfoEnabled())
255                             logger.info("Caught exception ", e);
256                     }
257                 }
258
259                 info.setArguments (params);
260
261                 ServerInterceptorIterator intercept_iter =
262                     orb.getInterceptorManager().getServerIterator();
263
264                 try
265                 {
266                     intercept_iter.iterate(info, ServerInterceptorIterator.RECEIVE_REQUEST);
267                 }
268                 catch(org.omg.CORBA.UserException JavaDoc ue)
269                 {
270                     if (ue instanceof org.omg.PortableInterceptor.
271
JavaDoc                        ForwardRequest)
272                     {
273
274                         org.omg.PortableInterceptor.ForwardRequest JavaDoc fwd =
275                             (org.omg.PortableInterceptor.ForwardRequest JavaDoc) ue;
276
277                         setLocationForward(new org.omg.PortableServer.
278
JavaDoc                            ForwardRequest(fwd.forward));
279                     }
280                 }
281                 catch (org.omg.CORBA.SystemException JavaDoc _sys_ex)
282                 {
283                     setSystemException(_sys_ex);
284                 }
285
286                 info = null;
287             }
288         }
289     }
290
291     public void set_result(org.omg.CORBA.Any JavaDoc res)
292     {
293         if( stream_based )
294             throw new RuntimeException JavaDoc("This ServerRequest is stream-based!");
295         result = res;
296     }
297
298     public void set_exception(org.omg.CORBA.Any JavaDoc ex)
299     {
300         if( stream_based )
301             throw new RuntimeException JavaDoc("This ServerRequest is stream-based!");
302         this.ex = ex;
303         status = ReplyStatusType_1_2._USER_EXCEPTION;
304     }
305
306
307     public void reply()
308     {
309         if( responseExpected() )
310         {
311             //shortcut for appligator
312
if (usePreconstructedReply)
313             {
314                 try
315                 {
316                     connection.sendReply( out );
317                 }
318                 catch( Exception JavaDoc ioe )
319                 {
320                     if (logger.isInfoEnabled())
321                         logger.info("Error replying to request!", ioe);
322                 }
323
324                 return;
325             }
326
327             if( logger.isDebugEnabled() )
328             {
329                 logger.debug( "ServerRequest: reply to " + operation() );
330             }
331
332             try
333             {
334                 if( out == null )
335                 {
336                     out =
337                         new ReplyOutputStream(requestId(),
338                                               ReplyStatusType_1_2.from_int(status),
339                                               in.getGIOPMinor(),
340                                               in.isLocateRequest(),
341                                               logger);
342                 }
343
344                 /*
345                  * DSI-based servers set results and user exceptions
346                  * using anys, so we have to treat this differently
347                  */

348                 if( !stream_based )
349                 {
350                     if( status == ReplyStatusType_1_2._USER_EXCEPTION )
351                     {
352                         out.write_string( ex.type().id() );
353                         ex.write_value( out );
354                     }
355                     else if( status == ReplyStatusType_1_2._NO_EXCEPTION )
356                     {
357                         if( result != null )
358                             result.write_value( out );
359
360                         if( args != null )
361                         {
362                             for( java.util.Enumeration JavaDoc e = args.enumerate();
363                                  e.hasMoreElements(); )
364                             {
365                                 org.jacorb.orb.NamedValue nv =
366                                     (org.jacorb.orb.NamedValue)e.nextElement();
367
368                                 if( nv.flags() != org.omg.CORBA.ARG_IN.value )
369                                 {
370                                     // in parameters are not returnd
371
try
372                                     {
373                                         nv.send( out );
374                                     }
375                                     catch (Exception JavaDoc ex)
376                                     {
377                                         throw new org.omg.CORBA.MARSHAL JavaDoc("Couldn't return (in)out arg of type "
378                                                                         + nv.value().type() + " in ServerRequest.");
379                                     }
380                                 }
381                             }
382                         }
383                     }
384                 }
385
386                 /*
387                  * these two exceptions are set in the same way for
388                  * both stream-based and DSI-based servers
389                  */

390                 if( status == ReplyStatusType_1_2._LOCATION_FORWARD )
391                 {
392                     out.write_Object( location_forward.forward_reference );
393                 }
394                 else if( status == ReplyStatusType_1_2._SYSTEM_EXCEPTION )
395                 {
396                     org.jacorb.orb.SystemExceptionHelper.write( out, sys_ex );
397                 }
398
399                 /*
400                  * everything is written to out by now, be it results
401                  * or exceptions.
402                  */

403
404                 connection.sendReply( out );
405             }
406             catch ( Exception JavaDoc ioe )
407             {
408                 if (logger.isInfoEnabled())
409                     logger.info("Error replying to request!", ioe);
410             }
411         }
412     }
413
414     /* ResponseHandler */
415
416     public org.omg.CORBA.portable.OutputStream JavaDoc createReply()
417     {
418         stream_based = true;
419
420         if( out != null )
421             // The reply was already created. This happens in oneway
422
// operations using SyncScope SYNC_WITH_SERVER, and does
423
// not do any harm.
424
return out;
425
426         if( !stream_based )
427             throw new INTERNAL JavaDoc("ServerRequest not stream-based!");
428
429         out =
430             new ReplyOutputStream(requestId(),
431                                   ReplyStatusType_1_2.NO_EXCEPTION,
432                                   in.getGIOPMinor(),
433                                   in.isLocateRequest(),
434                                   logger );
435
436         return out;
437     }
438
439     public org.omg.CORBA.portable.OutputStream JavaDoc createExceptionReply()
440     {
441         stream_based = true;
442
443         status = ReplyStatusType_1_2._USER_EXCEPTION;
444
445         out =
446             new ReplyOutputStream(requestId(),
447                                   ReplyStatusType_1_2.USER_EXCEPTION,
448                                   in.getGIOPMinor(),
449                                   in.isLocateRequest(),
450                                   logger );
451
452         return out;
453     }
454
455     /** our own: */
456
457     public void setSystemException(org.omg.CORBA.SystemException JavaDoc s)
458     {
459         status = ReplyStatusType_1_2._SYSTEM_EXCEPTION;
460
461         /* we need to create a new output stream here because a system exception may
462            have occurred *after* a no_exception request header was written onto the
463            original output stream*/

464
465
466         out = new ReplyOutputStream(requestId(),
467                                     ReplyStatusType_1_2.SYSTEM_EXCEPTION,
468                                     in.getGIOPMinor(),
469                                     in.isLocateRequest(),
470                                     logger);
471
472         String JavaDoc msg = s.getMessage();
473         if (msg != null)
474             out.addServiceContext (createExceptionDetailMessage (msg));
475
476         sys_ex = s;
477     }
478
479     /**
480      * Creates a ServiceContext for transmitting an exception detail message,
481      * as per section 1.15.2 of the Java Mapping.
482      */

483     private ServiceContext JavaDoc createExceptionDetailMessage (String JavaDoc message)
484     {
485         CDROutputStream out = new CDROutputStream();
486         out.beginEncapsulatedArray();
487         out.write_wstring(message);
488         return new ServiceContext JavaDoc (org.omg.IOP.ExceptionDetailMessage.value,
489                                    out.getBufferCopy());
490     }
491
492     public void setLocationForward(org.omg.PortableServer.ForwardRequest JavaDoc r)
493     {
494         status = ReplyStatusType_1_2._LOCATION_FORWARD;
495
496         out = new ReplyOutputStream(requestId(),
497                                     ReplyStatusType_1_2.LOCATION_FORWARD,
498                                     in.getGIOPMinor(),
499                                     in.isLocateRequest(),
500                                     logger );
501         location_forward = r;
502     }
503
504     /**
505      * @return the InputStream. This operation sets the
506      * request be stream-based, ie. all attempts to extract
507      * data using DII-based operations will throw exceptions
508      * For internal access to the stream use get_in()
509      *
510      */

511
512     public org.jacorb.orb.CDRInputStream getInputStream()
513     {
514         stream_based = true;
515         return in;
516     }
517
518     public ReplyOutputStream getReplyOutputStream()
519     {
520         if (out == null)
521             createReply();
522
523         stream_based = true;
524         return out;
525     }
526
527     public boolean responseExpected()
528     {
529         return Messages.responseExpected(in.req_hdr.response_flags);
530     }
531
532     /**
533      * Returns the SyncScope of this request, as expressed in the
534      * header's response_flags. Note that here, on the server side,
535      * this no longer differentiates between SYNC_NONE and SYNC_WITH_TRANSPORT.
536      * The former is returned in both cases.
537      */

538     public short syncScope()
539     {
540         switch (in.req_hdr.response_flags)
541         {
542             case 0x00:
543                 return org.omg.Messaging.SYNC_NONE.value;
544             case 0x01:
545                 return org.omg.Messaging.SYNC_WITH_SERVER.value;
546             case 0x03:
547                 return org.omg.Messaging.SYNC_WITH_TARGET.value;
548             default:
549                 throw new RuntimeException JavaDoc ("Illegal SYNC_SCOPE: "
550                                             + in.req_hdr.response_flags);
551         }
552     }
553
554     public org.omg.CORBA.SystemException JavaDoc getSystemException()
555     {
556         return sys_ex;
557     }
558
559     public int requestId()
560     {
561         return in.req_hdr.request_id;
562     }
563
564     public byte[] objectKey()
565     {
566         return object_key;
567     }
568
569     /**
570      * <code>getScopes</code> returns the cached list of poa_names.
571      *
572      * @return a <code>List</code> value containing Strings separated by
573      * {@link org.jacorb.poa.POAConstants#OBJECT_KEY_SEPARATOR OBJECT_KEY_SEPARATOR}
574      */

575     public List getScopes ()
576     {
577         if (scopes == null || ( cachePoaNames == false ) )
578         {
579             scopes = POAUtil.extractScopedPOANames
580                 (POAUtil.extractPOAName (object_key));
581         }
582         return scopes;
583     }
584
585
586     public org.omg.IOP.ServiceContext JavaDoc[] getServiceContext()
587     {
588         return in.req_hdr.service_context;
589     }
590
591     public byte[] objectId()
592     {
593         return oid;
594     }
595
596     public boolean streamBased()
597     {
598         return stream_based;
599     }
600
601
602     public void setReference(org.omg.CORBA.Object JavaDoc o)
603     {
604         reference = o;
605     }
606
607     public org.omg.CORBA.Object JavaDoc getReference()
608     {
609         return reference;
610     }
611
612     public RequestInputStream get_in()
613     {
614         return in;
615     }
616
617     /**
618      * If a new output stream has to be created, the request itself isn't fixed
619      * to stream-based.
620      */

621
622     public ReplyOutputStream get_out()
623     {
624         if (out == null)
625             out = new ReplyOutputStream(requestId(),
626                                         ReplyStatusType_1_2.NO_EXCEPTION,
627                                         in.getGIOPMinor(),
628                                         in.isLocateRequest(),
629                                         logger );
630
631         return out;
632     }
633
634     public void setServerRequestInfo(ServerRequestInfoImpl info)
635     {
636         this.info = info;
637     }
638
639     public org.omg.CORBA.Object JavaDoc getForwardReference()
640     {
641         if (location_forward != null)
642             return location_forward.forward_reference;
643         else
644             return null;
645     }
646
647     public GIOPConnection getConnection()
648     {
649         return connection;
650     }
651
652     public void setUsePreconstructedReply(boolean use)
653     {
654         usePreconstructedReply = use;
655     }
656
657     /**
658      * If this request has a service context with timing policies,
659      * this method decodes them and puts them into the corresponding
660      * instance variables (requestStartTime, requestEndTime, replyEndTime).
661      */

662     private void getTimingPolicies()
663     {
664         ServiceContext JavaDoc ctx = in.getServiceContext(INVOCATION_POLICIES.value);
665         if (ctx != null)
666         {
667             CDRInputStream input = new CDRInputStream (null, ctx.context_data);
668             input.openEncapsulatedArray();
669             PolicyValue[] p = PolicyValueSeqHelper.read (input);
670             for (int i=0; i < p.length; i++)
671             {
672                 if (p[i].ptype == REQUEST_START_TIME_POLICY_TYPE.value)
673                     requestStartTime = Time.fromCDR (p[i].pvalue);
674                 else if (p[i].ptype == REQUEST_END_TIME_POLICY_TYPE.value)
675                     requestEndTime = Time.fromCDR (p[i].pvalue);
676                 else if (p[i].ptype == REPLY_END_TIME_POLICY_TYPE.value)
677                     replyEndTime = Time.fromCDR (p[i].pvalue);
678             }
679         }
680     }
681
682     /**
683      * Returns the time after which a reply to this request may no longer
684      * be obtained or returned to the client; null if no such time has
685      * been specified.
686      */

687     public UtcT getReplyEndTime()
688     {
689         return replyEndTime;
690     }
691
692     /**
693      * Returns the time after which this request may no longer be
694      * delivered to its target; null if no such time has been specified.
695      */

696     public UtcT getRequestEndTime()
697     {
698         return requestEndTime;
699     }
700
701     /**
702      * Returns the time after which this request may be delivered to
703      * its target; null if no such time has been specified.
704      */

705     public UtcT getRequestStartTime()
706     {
707         return requestStartTime;
708     }
709
710 }
711
Popular Tags