OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [CORBA/] [gnuRequest.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* gnuRequest.java --
2
   Copyright (C) 2005 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package gnu.CORBA;
40
 
41
import gnu.CORBA.CDR.BufferredCdrInput;
42
import gnu.CORBA.CDR.BufferedCdrOutput;
43
import gnu.CORBA.GIOP.MessageHeader;
44
import gnu.CORBA.GIOP.ReplyHeader;
45
import gnu.CORBA.GIOP.RequestHeader;
46
import gnu.CORBA.GIOP.CodeSetServiceContext;
47
import gnu.CORBA.Interceptor.gnuClientRequestInfo;
48
import gnu.CORBA.Poa.ORB_1_4;
49
 
50
import org.omg.CORBA.ARG_IN;
51
import org.omg.CORBA.ARG_INOUT;
52
import org.omg.CORBA.ARG_OUT;
53
import org.omg.CORBA.Any;
54
import org.omg.CORBA.BAD_INV_ORDER;
55
import org.omg.CORBA.BAD_PARAM;
56
import org.omg.CORBA.Bounds;
57
import org.omg.CORBA.COMM_FAILURE;
58
import org.omg.CORBA.CompletionStatus;
59
import org.omg.CORBA.Context;
60
import org.omg.CORBA.ContextList;
61
import org.omg.CORBA.Environment;
62
import org.omg.CORBA.ExceptionList;
63
import org.omg.CORBA.INV_POLICY;
64
import org.omg.CORBA.MARSHAL;
65
import org.omg.CORBA.NO_IMPLEMENT;
66
import org.omg.CORBA.NO_RESOURCES;
67
import org.omg.CORBA.NVList;
68
import org.omg.CORBA.NamedValue;
69
import org.omg.CORBA.ORB;
70
import org.omg.CORBA.Policy;
71
import org.omg.CORBA.Request;
72
import org.omg.CORBA.SystemException;
73
import org.omg.CORBA.TypeCode;
74
import org.omg.CORBA.UnknownUserException;
75
import org.omg.CORBA.portable.ObjectImpl;
76
import org.omg.IOP.ServiceContext;
77
import org.omg.IOP.TAG_CODE_SETS;
78
import org.omg.IOP.TAG_INTERNET_IOP;
79
import org.omg.IOP.TaggedComponent;
80
import org.omg.IOP.TaggedProfile;
81
import org.omg.PortableInterceptor.ClientRequestInfo;
82
import org.omg.PortableInterceptor.ClientRequestInterceptorOperations;
83
import org.omg.PortableInterceptor.ForwardRequest;
84
import org.omg.PortableInterceptor.InvalidSlot;
85
 
86
import java.io.IOException;
87
import java.io.InputStream;
88
import java.io.OutputStream;
89
 
90
import java.net.Socket;
91
 
92
import java.util.ArrayList;
93
 
94
/**
95
 * The implementation of the CORBA request.
96
 *
97
 * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
98
 */
99
public class gnuRequest extends Request implements Cloneable
100
{
101
  /**
102
   * The maximal supported GIOP version.
103
   */
104
  public static Version MAX_SUPPORTED = new Version(1, 2);
105
 
106
  /**
107
   * The initial pause that the Request makes when the required port is not
108
   * available.
109
   */
110
  public static int PAUSE_INITIAL = 50;
111
 
112
  /**
113
   * The number of repretetive attempts to get a required port, if it is not
114
   * immediately available.
115
   */
116
  public static int PAUSE_STEPS = 12;
117
 
118
  /**
119
   * The maximal pausing interval between two repetetive attempts. The interval
120
   * doubles after each unsuccessful attempt, but will not exceed this value.
121
   */
122
  public static int PAUSE_MAX = 1000;
123
 
124
  /**
125
   * The interceptor, listening the major request submission points.
126
   */
127
  ClientRequestInterceptorOperations m_interceptor;
128
 
129
  /**
130
   * The request info, used by interceptor.
131
   */
132
  ClientRequestInfo m_info = new gnuClientRequestInfo(this);
133
 
134
  /**
135
   * The empty byte array.
136
   */
137
  private static final RawReply EMPTY =
138
    new RawReply(null, new MessageHeader(), new byte[ 0 ]);
139
 
140
  /**
141
   * The context holder for methods ctx(Context) and ctx().
142
   */
143
  protected Context m_context;
144
 
145
  /**
146
   * The context list for method contexts().
147
   */
148
  protected ContextList m_context_list;
149
 
150
  /**
151
   * The request environment for holding the exception the has possibly been
152
   * thrown by the method being invoked.
153
   */
154
  protected Environment m_environment = new gnuEnvironment();
155
 
156
  /**
157
   * The list of all exceptions that can be thrown by the method being invoked.
158
   */
159
  protected ExceptionList m_exceptions = new gnuExceptionList();
160
 
161
  /**
162
   * The result, returned by the invoked method (function).
163
   */
164
  protected NamedValue m_result = new gnuNamedValue();
165
 
166
  /**
167
   * The exception id, received from the server, null if none.
168
   */
169
  protected String m_exception_id;
170
 
171
  /**
172
   * The thrown system exception.
173
   */
174
  protected SystemException m_sys_ex;
175
 
176
  /**
177
   * The invocation target.
178
   */
179
  protected org.omg.CORBA.Object m_target;
180
 
181
  /**
182
   * The name of the method being invoked.
183
   */
184
  protected String m_operation;
185
 
186
  /**
187
   * This field temporary remembers the value of the forwarded ior reference. If
188
   * it is not null, the request was forwarded and the effective target is not
189
   * the same as the default target.
190
   */
191
  public IOR m_forward_ior;
192
 
193
  /**
194
   * Is set when object, and not IOR is directly available.
195
   */
196
  public org.omg.CORBA.Object m_forwarding_target;
197
 
198
  /**
199
   * The flag, indicating that the request has been sent and the result is
200
   * already received.
201
   */
202
  protected boolean complete;
203
 
204
  /**
205
   * The flag, indicating that the response to this request must be ignored
206
   * (used with {@link #send_oneway()}).
207
   */
208
  protected boolean oneWay;
209
 
210
  /**
211
   * The flag, indicating that the request has been sent and no result is yet
212
   * received.
213
   */
214
  protected boolean running;
215
 
216
  /**
217
   * The request arguments.
218
   */
219
  protected gnuNVList m_args = new gnuNVList();
220
 
221
  /**
222
   * The request arguments in the case when they are directly written into the
223
   * parameter buffer.
224
   */
225
  protected StreamBasedRequest m_parameter_buffer;
226
 
227
  /**
228
   * The array of slots.
229
   */
230
  protected Any[] m_slots;
231
 
232
  /**
233
   * The request header currently in use.
234
   */
235
  protected RequestHeader m_rqh;
236
 
237
  /**
238
   * The reply header currently in use.
239
   */
240
  protected ReplyHeader m_rph;
241
 
242
  /**
243
   * The IOR of the target.
244
   */
245
  private IOR ior;
246
 
247
  /**
248
   * The ORB of the target.
249
   */
250
  private ORB orb;
251
 
252
  /**
253
   * The encoding, used to send the message.
254
   *
255
   * The default encoding is inherited from the set IOR (that string reference
256
   * can be encoded in either Big or Little endian). If the IOR encoding is not
257
   * known (for example, by obtaining the reference from the naming service),
258
   * the Big Endian is used.
259
   */
260
  private boolean Big_endian = true;
261
 
262
  /**
263
   * Set the IOR data, sufficient to find the invocation target. This also sets
264
   * default endian encoding for invocations.
265
   *
266
   * @see IOR.parse(String)
267
   */
268
  public void setIor(IOR an_ior)
269
  {
270
    ior = an_ior;
271
    setBigEndian(ior.Big_Endian);
272
  }
273
 
274
  /**
275
   * Used when redirecting request to another target.
276
   */
277
  gnuRequest redirected;
278
 
279
  /**
280
   * Get the IOR data, sufficient to find the invocation target.
281
   *
282
   * @return the IOR data.
283
   */
284
  public IOR getIor()
285
  {
286
    return ior;
287
  }
288
 
289
  /**
290
   * Set the ORB, related to the invocation target.
291
   */
292
  public void setORB(ORB an_orb)
293
  {
294
    orb = an_orb;
295
 
296
    // Take the interceptor from the ORB.
297
    if (orb instanceof OrbRestricted)
298
      m_interceptor = ((OrbRestricted) orb).iClient;
299
 
300
    if (m_interceptor != null && orb instanceof ORB_1_4)
301
      {
302
        m_slots = ((ORB_1_4) orb).ic_current.clone_slots();
303
      }
304
  }
305
 
306
  /**
307
   * Set the encoding that will be used to send the message. The default
308
   * encoding is inherited from the set IOR (that string reference can be
309
   * encoded in either Big or Little endian). If the IOR encoding is not known
310
   * (for example, by obtaining the reference from the naming service), the Big
311
   * Endian is used.
312
   *
313
   * @param use_big_endian true to use the Big Endian, false to use the Little
314
   * Endian encoding.
315
   */
316
  public void setBigEndian(boolean use_big_endian)
317
  {
318
    Big_endian = use_big_endian;
319
  }
320
 
321
  /**
322
   * The the method name to invoke.
323
   *
324
   * @param operation the method name.
325
   */
326
  public void setOperation(String operation)
327
  {
328
    m_operation = operation;
329
  }
330
 
331
  /**
332
   * Get the parameter stream, where the invocation arguments should be written
333
   * if they are written into the stream directly.
334
   */
335
  public StreamBasedRequest getParameterStream()
336
  {
337
    m_parameter_buffer = new StreamBasedRequest();
338
    m_parameter_buffer.request = this;
339
    m_parameter_buffer.setVersion(ior.Internet.version);
340
    m_parameter_buffer.setCodeSet(CodeSetServiceContext.negotiate(ior.Internet.CodeSets));
341
    m_parameter_buffer.setOrb(orb);
342
    m_parameter_buffer.setBigEndian(Big_endian);
343
 
344
    // For the old iiop versions, it is important to set the size
345
    // correctly.
346
    if (ior.Internet.version.until_inclusive(1, 1))
347
      {
348
        BufferedCdrOutput measure = new BufferedCdrOutput();
349
        measure.setOffset(12);
350
        if (m_rqh == null)
351
          m_rqh = new gnu.CORBA.GIOP.v1_0.RequestHeader();
352
        m_rqh.operation = m_operation;
353
        m_rqh.object_key = ior.key;
354
        m_rqh.write(measure);
355
        m_parameter_buffer.setOffset(12 + measure.buffer.size());
356
      }
357
 
358
    return m_parameter_buffer;
359
  }
360
 
361
  /**
362
   * Creates a shallow copy of this request.
363
   */
364
  public gnuRequest Clone()
365
  {
366
    try
367
      {
368
        return (gnuRequest) clone();
369
      }
370
    catch (CloneNotSupportedException ex)
371
      {
372
        throw new Unexpected(ex);
373
      }
374
  }
375
 
376
  /** {@inheritDoc} */
377
  public Any add_in_arg()
378
  {
379
    gnuNamedValue v = new gnuNamedValue();
380
    v.setFlags(ARG_IN.value);
381
    m_args.add(v);
382
    return v.value();
383
  }
384
 
385
  /** {@inheritDoc} */
386
  public Any add_inout_arg()
387
  {
388
    gnuNamedValue v = new gnuNamedValue();
389
    v.setFlags(ARG_INOUT.value);
390
    m_args.add(v);
391
    return v.value();
392
  }
393
 
394
  /** {@inheritDoc} */
395
  public Any add_named_in_arg(String name)
396
  {
397
    gnuNamedValue v = new gnuNamedValue();
398
    v.setFlags(ARG_IN.value);
399
    v.setName(name);
400
    m_args.add(v);
401
    return v.value();
402
  }
403
 
404
  /** {@inheritDoc} */
405
  public Any add_named_inout_arg(String name)
406
  {
407
    gnuNamedValue v = new gnuNamedValue();
408
    v.setFlags(ARG_INOUT.value);
409
    v.setName(name);
410
    m_args.add(v);
411
    return v.value();
412
  }
413
 
414
  /** {@inheritDoc} */
415
  public Any add_named_out_arg(String name)
416
  {
417
    gnuNamedValue v = new gnuNamedValue();
418
    v.setFlags(ARG_OUT.value);
419
    v.setName(name);
420
    m_args.add(v);
421
    return v.value();
422
  }
423
 
424
  /** {@inheritDoc} */
425
  public Any add_out_arg()
426
  {
427
    gnuNamedValue v = new gnuNamedValue();
428
    v.setFlags(ARG_OUT.value);
429
    m_args.add(v);
430
    return v.value();
431
  }
432
 
433
  /** {@inheritDoc} */
434
  public NVList arguments()
435
  {
436
    return m_args;
437
  }
438
 
439
  /** {@inheritDoc} */
440
  public ContextList contexts()
441
  {
442
    return m_context_list;
443
  }
444
 
445
  /** {@inheritDoc} */
446
  public Context ctx()
447
  {
448
    return m_context;
449
  }
450
 
451
  /** {@inheritDoc} */
452
  public void ctx(Context a_context)
453
  {
454
    m_context = a_context;
455
  }
456
 
457
  /** {@inheritDoc} */
458
  public Environment env()
459
  {
460
    return m_environment;
461
  }
462
 
463
  /** {@inheritDoc} */
464
  public ExceptionList exceptions()
465
  {
466
    return m_exceptions;
467
  }
468
 
469
  /** {@inheritDoc} */
470
  public void get_response() throws org.omg.CORBA.WrongTransaction
471
  {
472
    /**
473
     * The response is ready after it is received. FIXME implement context
474
     * checks and any other functionality, if required.
475
     */
476
  }
477
 
478
  /**
479
   * Submit the request, suspending the current thread until the answer is
480
   * received.
481
   *
482
   * This implementation requires to set the IOR property ({@link #setIOR(IOR)}
483
   * before calling this method.
484
   *
485
   * @throws BAD_INV_ORDER, minor code 0, if the IOR has not been previously
486
   * set.
487
   *
488
   * @throws SystemException if this exception has been thrown on remote side.
489
   * The exact exception type and the minor code are the same as they have been
490
   * for the exception, thrown on remoted side.
491
   */
492
  public synchronized void invoke() throws BAD_INV_ORDER
493
  {
494
    waitWhileBusy();
495
    complete = false;
496
    running = true;
497
 
498
    if (ior == null)
499
      throw new BAD_INV_ORDER("Set IOR property first");
500
 
501
    try
502
      {
503
        Forwardings:
504
        while (true)
505
          {
506
            try
507
              {
508
                p_invoke();
509
                break Forwardings;
510
              }
511
            catch (ForwardRequest e)
512
              {
513
                try
514
                  {
515
                    ObjectImpl impl = (ObjectImpl) e.forward;
516
                    SimpleDelegate delegate =
517
                      (SimpleDelegate) impl._get_delegate();
518
                    ior = delegate.getIor();
519
                  }
520
                catch (Exception ex)
521
                  {
522
                    BAD_PARAM bad =
523
                      new BAD_PARAM("Unsupported forwarding target");
524
                    bad.initCause(ex);
525
                    throw bad;
526
                  }
527
              }
528
          }
529
      }
530
    finally
531
      {
532
        running = false;
533
        complete = true;
534
      }
535
  }
536
 
537
  /** {@inheritDoc} */
538
  public String operation()
539
  {
540
    return m_operation;
541
  }
542
 
543
  /**
544
   * Get the orb, related to the invocation target.
545
   */
546
  public ORB orb()
547
  {
548
    return orb;
549
  }
550
 
551
  /** {@inheritDoc} */
552
  public boolean poll_response()
553
  {
554
    return complete && !running;
555
  }
556
 
557
  /** {@inheritDoc} */
558
  public NamedValue result()
559
  {
560
    return m_result;
561
  }
562
 
563
  /**
564
   * {@inheritDoc}
565
   *
566
   */
567
  public Any return_value()
568
  {
569
    return m_result.value();
570
  }
571
 
572
  /** {@inheritDoc} */
573
  public synchronized void send_deferred()
574
  {
575
    waitWhileBusy();
576
    new Thread()
577
      {
578
        public void run()
579
        {
580
          invoke();
581
        }
582
      }.start();
583
  }
584
 
585
  /**
586
   * Send a request and forget about it, not waiting for a response. This can be
587
   * done also for methods that normally are expected to return some values.
588
   *
589
   * TODO It is generally recommended to reuse the threads. Reuse?
590
   */
591
  public void send_oneway()
592
  {
593
    final gnuRequest cloned = Clone();
594
    cloned.oneWay = true;
595
 
596
    new Thread()
597
      {
598
        public void run()
599
        {
600
          cloned.invoke();
601
        }
602
      }.start();
603
  }
604
 
605
  /**
606
   * Set the argument list. This field is initialised as empty non null instance
607
   * by default, so the method is only used in cases when the direct replacement
608
   * is desired.
609
   *
610
   * @param a_args the argument list.
611
   */
612
  public void set_args(NVList a_args)
613
  {
614
    if (a_args instanceof gnuNVList)
615
      m_args = (gnuNVList) a_args;
616
    else
617
      {
618
        try
619
          {
620
            // In case if this is another implementation of the NVList.
621
            m_args.list.clear();
622
            for (int i = 0; i < a_args.count(); i++)
623
              {
624
                m_args.add(a_args.item(i));
625
              }
626
          }
627
        catch (Bounds ex)
628
          {
629
            Unexpected.error(ex);
630
          }
631
      }
632
  }
633
 
634
  /**
635
   * Set the context list that is later returned by the method
636
   * {@link #contexts()}.
637
   *
638
   * @param a_context_list a new context list.
639
   */
640
  public void set_context_list(ContextList a_context_list)
641
  {
642
    m_context_list = a_context_list;
643
  }
644
 
645
  /**
646
   * Set the exception container. This field is initialised as empty non null
647
   * instance by default, so the method is only used in cases when the direct
648
   * replacement is desired.
649
   *
650
   * @param a_environment the new exception container.
651
   */
652
  public void set_environment(Environment a_environment)
653
  {
654
    m_environment = a_environment;
655
  }
656
 
657
  /**
658
   * Set the list of exceptions. This field is initialised as empty non null
659
   * instance by default, so the method is only used in cases when the direct
660
   * replacement is desired.
661
   *
662
   * @param a_exceptions a list of exceptions.
663
   */
664
  public void set_exceptions(ExceptionList a_exceptions)
665
  {
666
    m_exceptions = a_exceptions;
667
  }
668
 
669
  /**
670
   * Set the operation name.
671
   *
672
   * @param a_operation the operation name.
673
   */
674
  public void set_operation(String a_operation)
675
  {
676
    m_operation = a_operation;
677
  }
678
 
679
  /**
680
   * Set the named value, returned as result. This field is initialised as empty
681
   * non null instance by default, so the method is only used in cases when the
682
   * direct replacement is desired.
683
   *
684
   * @param a_result the result keeper.
685
   */
686
  public void set_result(NamedValue a_result)
687
  {
688
    m_result = a_result;
689
  }
690
 
691
  /**
692
   * Set the type of the named value, returned as a result. Instantiates a new
693
   * instance of the result value.
694
   */
695
  public void set_return_type(TypeCode returns)
696
  {
697
    if (m_result == null || !returns.equal(m_result.value().type()))
698
      {
699
        m_result = new gnuNamedValue();
700
        m_result.value().type(returns);
701
      }
702
  }
703
 
704
  /**
705
   * Set the invocation target.
706
   *
707
   * @param a_target the CORBA object for that the method will be invoked.
708
   */
709
  public void set_target(org.omg.CORBA.Object a_target)
710
  {
711
    m_target = a_target;
712
  }
713
 
714
  /**
715
   * Do the actual invocation. This implementation requires to set the IOR
716
   * property ({@link #setIOR(IOR)} before calling this method.
717
   *
718
   * @throws BAD_INV_ORDER, minor code 0, if the IOR has not been previously set
719
   *           or if the direct argument addition is mixed with the direct
720
   *           argument writing into the output stream.
721
   * @return the server response in binary form.
722
   */
723
public synchronized RawReply submit()
724
    throws ForwardRequest
725
  {
726
    gnu.CORBA.GIOP.MessageHeader header = new gnu.CORBA.GIOP.MessageHeader();
727
 
728
    header.setBigEndian(Big_endian);
729
 
730
    // The byte order will be Big Endian by default.
731
    header.message_type = gnu.CORBA.GIOP.MessageHeader.REQUEST;
732
    header.version = useVersion(ior.Internet.version);
733
 
734
    RequestHeader rh = header.create_request_header();
735
    rh.operation = m_operation;
736
    rh.object_key = ior.key;
737
 
738
    // Update interceptor.
739
    m_rqh = rh;
740
 
741
    if (m_interceptor != null)
742
      m_interceptor.send_request(m_info);
743
 
744
    // Prepare the submission.
745
    BufferedCdrOutput request_part = new BufferedCdrOutput();
746
 
747
    request_part.setOffset(header.getHeaderSize());
748
    request_part.setVersion(header.version);
749
    request_part.setCodeSet(CodeSetServiceContext.negotiate(ior.Internet.CodeSets));
750
    request_part.setOrb(orb);
751
    request_part.setBigEndian(header.isBigEndian());
752
 
753
    // This also sets the stream encoding to the encoding, specified
754
    // in the header.
755
    rh.write(request_part);
756
 
757
    if (m_args != null && m_args.count() > 0)
758
      {
759
        write_parameters(header, request_part);
760
 
761
        if (m_parameter_buffer != null)
762
          throw new BAD_INV_ORDER("Please either add parameters or "
763
            + "write them into stream, but not both " + "at once.");
764
      }
765
 
766
    if (m_parameter_buffer != null)
767
      {
768
        write_parameter_buffer(header, request_part);
769
      }
770
 
771
    // Now the message size is available.
772
    header.message_size = request_part.buffer.size();
773
 
774
    Socket socket = null;
775
 
776
    java.lang.Object key = ior.Internet.host + ":" + ior.Internet.port;
777
 
778
    synchronized (SocketRepository.class)
779
      {
780
        socket = SocketRepository.get_socket(key);
781
      }
782
 
783
    try
784
      {
785
        long pause = PAUSE_INITIAL;
786
 
787
        if (socket == null)
788
          {
789
            // The IOException may be thrown under very heavy parallel
790
            // load. For some time, just wait, exceptiong the socket to free.
791
            Open: for (int i = 0; i < PAUSE_STEPS; i++)
792
              {
793
                try
794
                  {
795
                    if (orb instanceof OrbFunctional)
796
                      socket = ((OrbFunctional) orb).socketFactory.
797
                        createClientSocket(
798
                          ior.Internet.host, ior.Internet.port);
799
                    else
800
                      socket = new Socket(ior.Internet.host, ior.Internet.port);
801
                    break Open;
802
                  }
803
                catch (IOException ex)
804
                  {
805
                    try
806
                      {
807
                        // Expecting to free a socket via finaliser.
808
                        System.gc();
809
                        Thread.sleep(pause);
810
                        pause = pause * 2;
811
                        if (pause > PAUSE_MAX)
812
                          pause = PAUSE_MAX;
813
                      }
814
                    catch (InterruptedException iex)
815
                      {
816
                      }
817
                  }
818
              }
819
          }
820
 
821
        if (socket == null)
822
          throw new NO_RESOURCES(ior.Internet.host + ":" + ior.Internet.port
823
            + " in use");
824
        socket.setKeepAlive(true);
825
 
826
        OutputStream socketOutput = socket.getOutputStream();
827
 
828
        // Write the message header.
829
        header.write(socketOutput);
830
 
831
        // Write the request header and parameters (if present).
832
        request_part.buffer.writeTo(socketOutput);
833
 
834
        socketOutput.flush();
835
        if (!socket.isClosed() && !oneWay)
836
          {
837
            MessageHeader response_header = new MessageHeader();
838
            InputStream socketInput = socket.getInputStream();
839
            response_header.read(socketInput);
840
 
841
            byte[] r;
842
            if (orb instanceof OrbFunctional)
843
              {
844
                OrbFunctional fo = (OrbFunctional) orb;
845
                r = response_header.readMessage(socketInput, socket,
846
                  fo.TOUT_WHILE_READING, fo.TOUT_AFTER_RECEIVING);
847
              }
848
            else
849
              r = response_header.readMessage(socketInput, null, 0, 0);
850
 
851
            return new RawReply(orb, response_header, r);
852
          }
853
        else
854
          return EMPTY;
855
      }
856
    catch (IOException io_ex)
857
      {
858
        COMM_FAILURE m = new COMM_FAILURE("Unable to open a socket at "
859
          + ior.Internet.host + ":" + ior.Internet.port, 0xC9,
860
          CompletionStatus.COMPLETED_NO);
861
        m.initCause(io_ex);
862
        throw m;
863
      }
864
    finally
865
      {
866
        try
867
          {
868
            if (socket != null && !socket.isClosed())
869
              {
870
                socket.setSoTimeout(OrbFunctional.TANDEM_REQUESTS);
871
                SocketRepository.put_socket(key, socket);
872
              }
873
          }
874
        catch (IOException scx)
875
          {
876
            InternalError ierr = new InternalError();
877
            ierr.initCause(scx);
878
            throw ierr;
879
          }
880
      }
881
  }
882
 
883
  /** {@inheritDoc} */
884
  public org.omg.CORBA.Object target()
885
  {
886
    return m_target;
887
  }
888
 
889
  /**
890
   * Get the used version. Normally, it is better to respond using the same
891
   * version as it is specified in IOR, but not above the maximal supported
892
   * version.
893
   */
894
  public Version useVersion(Version desired)
895
  {
896
    if (desired.until_inclusive(MAX_SUPPORTED.major, MAX_SUPPORTED.minor))
897
      return desired;
898
    else
899
      return MAX_SUPPORTED;
900
  }
901
 
902
  /**
903
   * Wait while the response to request, submitted using
904
   * {@link #send_deferred()} or {@link #invoke()} (from other thread) is
905
   * returned.
906
   *
907
   * FIXME It is possible to rewrite this using Object.wait() and
908
   * Object.notify(), but be sure to prepare the test as well.
909
   */
910
  public synchronized void waitWhileBusy()
911
  {
912
    // Waiting constants.
913
    long wait = 10;
914
    long increment = 2;
915
    long max = 5000;
916
 
917
    while (running)
918
      {
919
        try
920
          {
921
            Thread.sleep(wait);
922
            if (wait < max)
923
              wait = wait * increment;
924
          }
925
        catch (InterruptedException ex)
926
          {
927
          }
928
      }
929
  }
930
 
931
  /**
932
   * Do actual invocation. This method recursively calls itself if the
933
   * redirection is detected.
934
   */
935
  private void p_invoke()
936
    throws SystemException, ForwardRequest
937
  {
938
    RawReply response = submit();
939
 
940
    // If this is a one way message, do not care about the response.
941
    if (oneWay && response == EMPTY)
942
      return;
943
 
944
    if (m_rph == null)
945
      m_rph = response.header.create_reply_header();
946
 
947
    BufferredCdrInput input = response.getStream();
948
    input.setOrb(orb);
949
 
950
    m_rph.read(input);
951
 
952
    // The stream must be aligned sinve v1.2, but only once.
953
    boolean align = response.header.version.since_inclusive(1, 2);
954
 
955
    switch (m_rph.reply_status)
956
      {
957
        case ReplyHeader.NO_EXCEPTION:
958
 
959
          NamedValue arg;
960
 
961
          // Read return value, if set.
962
          if (m_result != null)
963
            {
964
              if (align)
965
                {
966
                  input.align(8);
967
                  align = false;
968
                }
969
              m_result.value().read_value(input, m_result.value().type());
970
            }
971
 
972
          // Read returned parameters, if set.
973
          if (m_args != null)
974
            for (int i = 0; i < m_args.count(); i++)
975
              {
976
                try
977
                  {
978
                    arg = m_args.item(i);
979
 
980
                    // Both ARG_INOUT and ARG_OUT have this binary flag set.
981
                    if ((arg.flags() & ARG_OUT.value) != 0)
982
                      {
983
                        if (align)
984
                          {
985
                            input.align(8);
986
                            align = false;
987
                          }
988
 
989
                        arg.value().read_value(input, arg.value().type());
990
                      }
991
                  }
992
                catch (Bounds ex)
993
                  {
994
                    Unexpected.error(ex);
995
                  }
996
              }
997
 
998
          if (m_interceptor != null)
999
            m_interceptor.receive_reply(m_info);
1000
 
1001
          break;
1002
 
1003
        case ReplyHeader.SYSTEM_EXCEPTION:
1004
          if (align)
1005
            {
1006
              input.align(8);
1007
              align = false;
1008
            }
1009
          readExceptionId(input);
1010
 
1011
          m_sys_ex = ObjectCreator.readSystemException(input,
1012
            m_rph.service_context);
1013
          m_environment.exception(m_sys_ex);
1014
 
1015
          if (m_interceptor != null)
1016
            m_interceptor.receive_exception(m_info);
1017
 
1018
          throw m_sys_ex;
1019
 
1020
        case ReplyHeader.USER_EXCEPTION:
1021
          if (align)
1022
            {
1023
              input.align(8);
1024
              align = false;
1025
            }
1026
          readExceptionId(input);
1027
 
1028
          // Prepare an Any that will hold the exception.
1029
          gnuAny exc = new gnuAny();
1030
          exc.setOrb(orb);
1031
 
1032
          exc.insert_Streamable(new StreamHolder(input));
1033
 
1034
          UnknownUserException unuex = new UnknownUserException(exc);
1035
          m_environment.exception(unuex);
1036
 
1037
          if (m_interceptor != null)
1038
            m_interceptor.receive_exception(m_info);
1039
 
1040
          break;
1041
 
1042
        case ReplyHeader.LOCATION_FORWARD_PERM:
1043
        case ReplyHeader.LOCATION_FORWARD:
1044
          if (response.header.version.since_inclusive(1, 2))
1045
            input.align(8);
1046
 
1047
          IOR forwarded = new IOR();
1048
          try
1049
            {
1050
              forwarded._read_no_endian(input);
1051
            }
1052
          catch (IOException ex)
1053
            {
1054
              new MARSHAL("Cant read forwarding info", 5103,
1055
                CompletionStatus.COMPLETED_NO);
1056
            }
1057
 
1058
          setIor(forwarded);
1059
 
1060
          m_forward_ior = forwarded;
1061
 
1062
          if (m_interceptor != null)
1063
            m_interceptor.receive_other(m_info);
1064
 
1065
          // Repeat with the forwarded information.
1066
          p_invoke();
1067
          return;
1068
 
1069
        default:
1070
          throw new MARSHAL("Unknow reply status", 8100 + m_rph.reply_status,
1071
            CompletionStatus.COMPLETED_NO);
1072
      }
1073
  }
1074
 
1075
  /**
1076
   * Read exception id without changing the stream pointer position.
1077
   */
1078
  void readExceptionId(BufferredCdrInput input)
1079
  {
1080
    input.mark(2048);
1081
    m_exception_id = input.read_string();
1082
    input.reset();
1083
  }
1084
 
1085
  /**
1086
   * Write the operation parameters.
1087
   *
1088
   * @param header the message header
1089
   * @param request_part the stream to write parameters into
1090
   *
1091
   * @throws MARSHAL if the attempt to write the parameters has failde.
1092
   */
1093
  protected void write_parameter_buffer(MessageHeader header,
1094
    BufferedCdrOutput request_part
1095
  ) throws MARSHAL
1096
  {
1097
    try
1098
      {
1099
        if (header.version.since_inclusive(1, 2))
1100
          {
1101
            request_part.align(8);
1102
          }
1103
        m_parameter_buffer.buffer.writeTo(request_part);
1104
      }
1105
    catch (IOException ex)
1106
      {
1107
        MARSHAL m = new MARSHAL("Unable to write method arguments to CDR output.");
1108
        m.minor = Minor.CDR;
1109
        throw m;
1110
      }
1111
  }
1112
 
1113
  /**
1114
   * Write the operation parameters.
1115
   *
1116
   * @param header the message header
1117
   * @param request_part the stream to write parameters into
1118
   *
1119
   * @throws MARSHAL if the attempt to write the parameters has failde.
1120
   */
1121
  protected void write_parameters(MessageHeader header,
1122
    BufferedCdrOutput request_part
1123
  ) throws MARSHAL
1124
  {
1125
    // Align after 1.2, but only once.
1126
    boolean align = header.version.since_inclusive(1, 2);
1127
    NamedValue para;
1128
 
1129
    try
1130
      {
1131
        // Write parameters now.
1132
        for (int i = 0; i < m_args.count(); i++)
1133
          {
1134
            para = m_args.item(i);
1135
 
1136
            // This bit is set both for ARG_IN and ARG_INOUT
1137
            if ((para.flags() & ARG_IN.value) != 0)
1138
              {
1139
                if (align)
1140
                  {
1141
                    request_part.align(8);
1142
                    align = false;
1143
                  }
1144
                para.value().write_value(request_part);
1145
              }
1146
          }
1147
      }
1148
    catch (Bounds ex)
1149
      {
1150
        InternalError ierr = new InternalError();
1151
        ierr.initCause(ex);
1152
        throw ierr;
1153
      }
1154
  }
1155
 
1156
  /* **************Implementation of the request info operations. ***** */
1157
 
1158
  /**
1159
   * Add context to request.
1160
   */
1161
  public void add_request_service_context(ServiceContext service_context,
1162
    boolean replace
1163
  )
1164
  {
1165
    m_rqh.addContext(service_context, replace);
1166
  }
1167
 
1168
  /**
1169
   * Get the Internet profile as an effective profile.
1170
   */
1171
  public TaggedProfile effective_profile()
1172
  {
1173
    BufferedCdrOutput buf = new BufferedCdrOutput(512);
1174
    buf.setOrb(orb);
1175
    ior.Internet.write(buf);
1176
 
1177
    TaggedProfile p = new TaggedProfile();
1178
    p.tag = TAG_INTERNET_IOP.value;
1179
    p.profile_data = buf.buffer.toByteArray();
1180
    return p;
1181
  }
1182
 
1183
  /**
1184
   * Return either target or forwarded targed.
1185
   */
1186
  public org.omg.CORBA.Object effective_target()
1187
  {
1188
    return new IorObject(orb, ior);
1189
  }
1190
 
1191
  /**
1192
   * Get effective component with the give id from the Internet profile.
1193
   */
1194
  public TaggedComponent get_effective_component(int id)
1195
    throws BAD_PARAM
1196
  {
1197
    if (id == TAG_CODE_SETS.value)
1198
      {
1199
        // Codesets are encoded separately.
1200
        BufferedCdrOutput buf = new BufferedCdrOutput(512);
1201
        buf.setOrb(orb);
1202
        ior.Internet.CodeSets.write(buf);
1203
 
1204
        TaggedComponent t = new TaggedComponent();
1205
        t.tag = TAG_CODE_SETS.value;
1206
        t.component_data = buf.buffer.toByteArray();
1207
        return t;
1208
      }
1209
    else
1210
      {
1211
        for (int i = 0; i < ior.Internet.components.size(); i++)
1212
          {
1213
            TaggedComponent c =
1214
              (TaggedComponent) ior.Internet.components.get(i);
1215
            if (c.tag == id)
1216
              return c;
1217
          }
1218
      }
1219
    throw new BAD_PARAM("No component " + id + " in the Internet profile", 28,
1220
      CompletionStatus.COMPLETED_MAYBE
1221
    );
1222
  }
1223
 
1224
  /**
1225
   * Get all components with the given id from the internet profile.
1226
   */
1227
  public TaggedComponent[] get_effective_components(int id)
1228
    throws BAD_PARAM
1229
  {
1230
    if (id == TAG_CODE_SETS.value)
1231
      return new TaggedComponent[] { get_effective_component(TAG_CODE_SETS.value) };
1232
    else
1233
      {
1234
        ArrayList components = new ArrayList(ior.Internet.components.size());
1235
        for (int i = 0; i < ior.Internet.components.size(); i++)
1236
          {
1237
            TaggedComponent c =
1238
              (TaggedComponent) ior.Internet.components.get(i);
1239
            if (c.tag == id)
1240
              components.add(c);
1241
          }
1242
        if (components.size() == 0)
1243
          throw new BAD_PARAM("No component " + id +
1244
            " in the Internet profile", 28, CompletionStatus.COMPLETED_MAYBE
1245
          );
1246
        else
1247
          {
1248
            TaggedComponent[] t = new TaggedComponent[ components.size() ];
1249
            for (int i = 0; i < t.length; i++)
1250
              t [ i ] = (TaggedComponent) components.get(i);
1251
            return t;
1252
          }
1253
      }
1254
  }
1255
 
1256
  /**
1257
   * This should be not implemented up till jdk 1.5 inclusive.
1258
   */
1259
  public Policy get_request_policy(int type) throws INV_POLICY
1260
  {
1261
    throw new NO_IMPLEMENT();
1262
  }
1263
 
1264
  /** @inheritDoc */
1265
  public String received_exception_id()
1266
  {
1267
    return m_exception_id;
1268
  }
1269
 
1270
  /** @inheritDoc */
1271
  public Any received_exception()
1272
  {
1273
    if (m_exception_id == null)
1274
      return null;
1275
 
1276
    if (m_sys_ex != null)
1277
      {
1278
        Any a = orb.create_any();
1279
        ObjectCreator.insertSysException(a, m_sys_ex);
1280
        return a;
1281
      }
1282
 
1283
    Exception mex = m_environment.exception();
1284
 
1285
    UnknownUserException ex = (UnknownUserException) mex;
1286
    if (ex == null)
1287
      return null;
1288
    else
1289
      return ex.except;
1290
  }
1291
 
1292
  /**
1293
   * Return the forwarded reference, null if none.
1294
   */
1295
  public org.omg.CORBA.Object forward_reference()
1296
  {
1297
    if (m_forwarding_target != null)
1298
      return m_forwarding_target;
1299
 
1300
    if (m_forward_ior != null)
1301
      return new IorObject(orb, m_forward_ior);
1302
    else
1303
      return null;
1304
  }
1305
 
1306
  /**
1307
   * Get the slot from the slot array inside this request.
1308
   */
1309
  public Any get_slot(int id) throws InvalidSlot
1310
  {
1311
    try
1312
      {
1313
        return m_slots [ id ];
1314
      }
1315
    catch (Exception e)
1316
      {
1317
        throw new InvalidSlot("slot id " + id + ":" + e);
1318
      }
1319
  }
1320
 
1321
  /**
1322
   * Get the reply status.
1323
   */
1324
  public short reply_status()
1325
  {
1326
    if (m_rph == null)
1327
      throw new BAD_INV_ORDER("Request not yet sent", 14,
1328
        CompletionStatus.COMPLETED_NO
1329
      );
1330
    return (short) m_rph.reply_status;
1331
  }
1332
 
1333
  /**
1334
   * Get the request id.
1335
   */
1336
  public int request_id()
1337
  {
1338
    return m_rqh.request_id;
1339
  }
1340
 
1341
  /**
1342
   * Return true if the response is expected.
1343
   */
1344
  public boolean response_expected()
1345
  {
1346
    return !oneWay;
1347
  }
1348
 
1349
  /**
1350
   * Determines how far the request shall progress before control is returned to
1351
   * the client. However up till JDK 1.5 inclusive this method always returns
1352
   * SYNC_WITH_TRANSPORT.
1353
   *
1354
   * @return {@link org.omg.Messaging.SYNC_WITH_TRANSPORT.value (1), always.
1355
   *
1356
   * @specnote as defined in the Suns 1.5 JDK API.
1357
   */
1358
  public short sync_scope()
1359
  {
1360
    return org.omg.Messaging.SYNC_WITH_TRANSPORT.value;
1361
  }
1362
 
1363
  /** @inheritDoc */
1364
  public ServiceContext get_request_service_context(int ctx_name)
1365
    throws BAD_PARAM
1366
  {
1367
    return gnu.CORBA.GIOP.ServiceContext.findContext(ctx_name,
1368
      m_rqh.service_context
1369
    );
1370
  }
1371
 
1372
  /** @inheritDoc */
1373
  public ServiceContext get_reply_service_context(int ctx_name)
1374
    throws BAD_PARAM
1375
  {
1376
    if (m_rph == null)
1377
      throw new BAD_INV_ORDER("Reply context not yet available");
1378
    return gnu.CORBA.GIOP.ServiceContext.findContext(ctx_name,
1379
      m_rph.service_context
1380
    );
1381
  }
1382
 
1383
  /** @inheritDoc */
1384
  public String[] operation_context()
1385
  {
1386
    return ice_contexts();
1387
  }
1388
 
1389
  /**
1390
   * Get contexts as required by interceptor.
1391
   */
1392
  public String[] ice_contexts()
1393
  {
1394
    if (m_context_list == null)
1395
      return new String[ 0 ];
1396
    else
1397
      {
1398
        try
1399
          {
1400
            String[] cn = new String[ m_context_list.count() ];
1401
            for (int i = 0; i < cn.length; i++)
1402
              cn [ i ] = m_context_list.item(i);
1403
            return cn;
1404
          }
1405
        catch (Bounds e)
1406
          {
1407
            throw new Unexpected(e);
1408
          }
1409
      }
1410
  }
1411
 
1412
  /**
1413
   * Check if the call is done via DII.
1414
   */
1415
  public void checkDii()
1416
  {
1417
    if (m_parameter_buffer != null)
1418
      throw new NO_RESOURCES("The invocation method provides " +
1419
        "no access to this resource. DII call required.", 1,
1420
        CompletionStatus.COMPLETED_MAYBE
1421
      );
1422
  }
1423
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.