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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [gnu/] [CORBA/] [gnuRequest.java] - Blame information for rev 14

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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