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

Subversion Repositories scarts

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* RmiUtilities.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.javax.rmi.CORBA;
40
 
41
import gnu.CORBA.OrbFunctional;
42
import gnu.CORBA.Minor;
43
import gnu.CORBA.Unexpected;
44
import gnu.CORBA.CDR.Vio;
45
import gnu.CORBA.CDR.gnuRuntime;
46
import gnu.CORBA.CDR.gnuValueStream;
47
import gnu.CORBA.CDR.HeadlessInput;
48
 
49
import org.omg.CORBA.MARSHAL;
50
import org.omg.CORBA.StringValueHelper;
51
import org.omg.CORBA.WStringValueHelper;
52
import org.omg.CORBA.portable.Delegate;
53
import org.omg.CORBA.portable.InputStream;
54
import org.omg.CORBA.portable.ObjectImpl;
55
import org.omg.CORBA.portable.OutputStream;
56
import org.omg.CORBA.portable.ValueBase;
57
import org.omg.PortableServer.POA;
58
import org.omg.PortableServer.POAHelper;
59
import org.omg.PortableServer.Servant;
60
import org.omg.PortableServer.POAManagerPackage.State;
61
import org.omg.SendingContext.RunTime;
62
 
63
import java.io.ByteArrayOutputStream;
64
import java.io.DataOutputStream;
65
import java.io.Externalizable;
66
import java.io.IOException;
67
import java.io.ObjectInputStream;
68
import java.io.ObjectOutputStream;
69
import java.io.Serializable;
70
import java.lang.reflect.Field;
71
import java.lang.reflect.Method;
72
import java.lang.reflect.Modifier;
73
import java.rmi.Remote;
74
import java.security.MessageDigest;
75
import java.util.Arrays;
76
import java.util.Comparator;
77
import java.util.Iterator;
78
import java.util.TreeSet;
79
import java.util.WeakHashMap;
80
 
81
import javax.rmi.PortableRemoteObject;
82
import javax.rmi.CORBA.Stub;
83
import javax.rmi.CORBA.Tie;
84
import javax.rmi.CORBA.Util;
85
 
86
/**
87
 * Defines methods that must be accessible in several derived classes.
88
 *
89
 * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
90
 */
91
public class RmiUtilities
92
{
93
  /**
94
   * The currently used RMI-IIOP version format.
95
   */
96
  public static byte VERSION = 1;
97
 
98
  /**
99
   * The non - writable class fields.
100
   */
101
  static final int NON_WRITABLE = Modifier.STATIC | Modifier.TRANSIENT;
102
 
103
  /**
104
   * The standard String repository Id.
105
   */
106
  public static final String RMI_STRING_ID = StringValueHelper.id();
107
 
108
  /**
109
   * The standard Class repository Id.
110
   */
111
  public static final String RMI_CLASS_ID = "RMI:javax.rmi.CORBA.ClassDesc:2BABDA04587ADCCC:CFBF02CF5294176B";
112
 
113
  /**
114
   * The standard string array repository Id.
115
   */
116
  public static final String RMI_STRING_ARRAY_ID = "RMI:[Ljava.lang.String;:071DA8BE7F971128:A0F0A4387A3BB342";
117
 
118
  /**
119
   * An instance of the wide string value helper for writing strings.
120
   */
121
  static WStringValueHelper wStringValueHelper = new WStringValueHelper();
122
 
123
  /**
124
   * Set of serializable classes that have .writeObject and .readObject defined.
125
   * Contains weak references to ensure that the classes will be unloadable.
126
   */
127
  WeakHashMap io_format = new WeakHashMap();
128
 
129
  /**
130
   * The standard IO format with no .writeObject and .readObject defined.
131
   */
132
  static final Object STANDARD = new Object();
133
 
134
  /**
135
   * The custom IO format with .writeObject and .readObject defined,
136
   * defaultWriteObject called.
137
   */
138
  static final Object CUSTOM_DWO = new Object();
139
 
140
  /**
141
   * The custom IO format with .writeObject and .readObject defined,
142
   * defaultWriteObject has not been called.
143
   */
144
  static final Object CUSTOM_NO_DWO = new Object();
145
 
146
  /**
147
   * The arguments for readObject.
148
   */
149
  static final Class[] READ_OBJECT_ARGS = new Class[] { ObjectInputStream.class };
150
 
151
  /**
152
   * The arguments for writeObject.
153
   */
154
  static final Class[] WRITE_OBJECT_ARGS = new Class[] { ObjectOutputStream.class };
155
 
156
  /**
157
   * The undocumented field that is heading the Sun's object data, written with
158
   * writeObject.
159
   */
160
  static final int S_X = 16908034;
161
 
162
  /**
163
   * Write all fields of the passed value.
164
   */
165
  void writeFields(OutputStream an_output, Serializable object)
166
  {
167
    org.omg.CORBA_2_3.portable.OutputStream output = (org.omg.CORBA_2_3.portable.OutputStream) an_output;
168
    try
169
      {
170
        Class o_class = object.getClass();
171
        Field[] fields = getWritableFields(o_class);
172
        Field f;
173
 
174
        Class fc;
175
 
176
        for (int i = 0; i < fields.length; i++)
177
          {
178
            f = fields[i];
179
            fc = f.getType();
180
            Object v = f.get(object);
181
 
182
            if (fc == String.class)
183
              {
184
                output.write_value((Serializable) v, wStringValueHelper);
185
              }
186
            else if (fc == int.class)
187
              output.write_long(((Integer) v).intValue());
188
            else if (fc == long.class)
189
              output.write_longlong(((Number) v).longValue());
190
            else if (fc == double.class)
191
              output.write_double(((Number) v).doubleValue());
192
            else if (fc == float.class)
193
              output.write_float(((Number) v).floatValue());
194
            else if (fc == boolean.class)
195
              output.write_boolean(((Boolean) v).booleanValue());
196
            else if (fc == short.class)
197
              output.write_short(((Number) v).shortValue());
198
            else if (fc == byte.class)
199
              output.write_octet(((Number) v).byteValue());
200
            else if (fc == char.class)
201
              output.write_wchar(((Character) v).charValue());
202
            else
203
              {
204
                if (!fc.isInterface() && Remote.class.isAssignableFrom(fc))
205
                  fc = getExportedInterface(fc);
206
                writeMember(output, v, fc);
207
              }
208
          }
209
      }
210
    catch (Exception ex)
211
      {
212
        MARSHAL m = new MARSHAL("Cannot write " + object);
213
        m.minor = Minor.ValueFields;
214
        m.initCause(ex);
215
        throw m;
216
      }
217
  }
218
 
219
  /**
220
   * Write a memeber (field) of the data structure.
221
   */
222
  void writeMember(org.omg.CORBA_2_3.portable.OutputStream output,
223
    Object object, Class xClass)
224
  {
225
    if (output instanceof gnuValueStream)
226
      {
227
        gnuRuntime g = ((gnuValueStream) output).getRunTime();
228
        // Reset the target as we are already beyond the critical point
229
        // where is must have the value being written.
230
        if (g != null)
231
          g.target = null;
232
      }
233
    if (Serializable.class.isAssignableFrom(xClass)
234
      || Remote.class.isAssignableFrom(xClass))
235
      {
236
        // Object handles null reference on its own.
237
        if (org.omg.CORBA.Object.class.isAssignableFrom(xClass)
238
          || Remote.class.isAssignableFrom(xClass))
239
          {
240
            if (object == null)
241
              output.write_Object(null);
242
            else if (isTieRequired(object))
243
              exportTie(output, object, xClass);
244
            else
245
              writeValue(output, (Serializable) object);
246
          }
247
        else
248
          output.write_value((Serializable) object, xClass);
249
      }
250
    else
251
      {
252
        MARSHAL m = new MARSHAL(xClass + " is not Serializable");
253
        m.minor = Minor.NonSerializable;
254
        throw m;
255
      }
256
  }
257
 
258
  /**
259
   * Check if the object must be wrapped into Tie, connected to the ORB and then
260
   * the corresponding Stub be written.
261
   */
262
  public boolean isTieRequired(Object object)
263
  {
264
    return object instanceof Remote && !(object instanceof Stub);
265
  }
266
 
267
  /**
268
   * Get the interface under that the class of this object must be exposed. The
269
   * interface must be derived from Remote.
270
   */
271
  Class getExportedInterface(Object object)
272
    throws MARSHAL
273
  {
274
    Class fc = null;
275
    Class[] interfaces = object.getClass().getInterfaces();
276
    for (int i = 0; i < interfaces.length; i++)
277
      {
278
        if (!Remote.class.equals(interfaces[i]))
279
          if (Remote.class.isAssignableFrom(interfaces[i]))
280
            {
281
              if (fc == null)
282
                fc = interfaces[i];
283
              else
284
                {
285
                  MARSHAL m = new MARSHAL("Both " + fc + " and " + interfaces[i]
286
                  + " extends Remote");
287
                  m.minor = Minor.TargetConversion;
288
                  throw m;
289
                }
290
            }
291
      }
292
    if (fc == null)
293
      {
294
        MARSHAL m = new MARSHAL(object.getClass()
295
        + " does not implement any interface, derived from Remote");
296
        m.minor = Minor.TargetConversion;
297
        throw m;
298
      }
299
    return fc;
300
  }
301
 
302
  /**
303
   * Get the persistent hash code for the given class, as defined by OMG
304
   * standard. The inheritance, field names and types (but not the visibility)
305
   * are taken into consideration as well as the presence of the writeObject
306
   * method are taken into consideration. The class name and methods, if any,
307
   * are not taken into consideration.
308
   */
309
  public static long getHashCode(Class c)
310
  {
311
    Class of = c.isArray() ? c.getComponentType() : null;
312
    if (c.isArray()
313
      && ((!Serializable.class.isAssignableFrom(of) || of.isPrimitive() || Remote.class.isAssignableFrom(of))))
314
      return 0;
315
    if (!Serializable.class.isAssignableFrom(c))
316
      return 0;
317
    try
318
      {
319
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
320
        DataOutputStream out = new DataOutputStream(bout);
321
 
322
        Class superClass = c.getSuperclass();
323
        if (superClass != null)
324
          out.writeLong(getHashCode(superClass));
325
 
326
        int writeObjectPresentCode;
327
        try
328
          {
329
            c.getDeclaredMethod("writeObject",
330
              new Class[] { ObjectOutputStream.class });
331
            writeObjectPresentCode = 2; // Exists.
332
          }
333
        catch (NoSuchMethodException e)
334
          {
335
            writeObjectPresentCode = 1; // Missing.
336
          }
337
        out.writeInt(writeObjectPresentCode);
338
 
339
        Field[] fields = c.getDeclaredFields();
340
 
341
        Arrays.sort(fields, new Comparator()
342
        {
343
          public int compare(Object a, Object b)
344
          {
345
            Field fa = (Field) a;
346
            Field fb = (Field) b;
347
            return fa.getName().compareTo(fb.getName());
348
          }
349
        });
350
 
351
        Field f;
352
        for (int i = 0; i < fields.length; i++)
353
          {
354
            f = fields[i];
355
            if ((f.getModifiers() & NON_WRITABLE) == 0)
356
              {
357
                out.writeUTF(f.getName());
358
                out.writeUTF(getDescriptor(f.getType()));
359
              }
360
          }
361
 
362
        out.flush();
363
        out.close();
364
        MessageDigest shaDigest;
365
        try
366
          {
367
            shaDigest = MessageDigest.getInstance("SHA");
368
          }
369
        catch (Exception ex)
370
          {
371
            throw new InternalError("SHA digesting algorithm is not available");
372
          }
373
 
374
        // Return the digest value to the calling
375
        // method as an array of bytes.
376
        byte[] sha = shaDigest.digest(bout.toByteArray());
377
 
378
        long hash = 0;
379
        for (int i = 0; i < Math.min(8, sha.length); i++)
380
          {
381
            hash += (long) (sha[i] & 255) << (i * 8);
382
          }
383
        return hash;
384
      }
385
    catch (IOException ioex)
386
      {
387
        throw new Unexpected(ioex);
388
      }
389
  }
390
 
391
  /**
392
   * Converts to hexadecimal string, supplementing leading zeros.
393
   */
394
  public static String toHex(long l)
395
  {
396
    StringBuffer b = new StringBuffer();
397
    b.append(Long.toHexString(l).toUpperCase());
398
    while (b.length() < 16)
399
      b.insert(0, '0');
400
    return b.toString();
401
  }
402
 
403
  /**
404
   * Returns a <code>String</code> representing the type-encoding of a class.
405
   */
406
  static String getDescriptor(Class type)
407
  {
408
    if (type.equals(boolean.class))
409
      return "Z";
410
    if (type.equals(byte.class))
411
      return "B";
412
    if (type.equals(short.class))
413
      return "S";
414
    if (type.equals(char.class))
415
      return "C";
416
    if (type.equals(int.class))
417
      return "I";
418
    if (type.equals(long.class))
419
      return "J";
420
    if (type.equals(float.class))
421
      return "F";
422
    if (type.equals(double.class))
423
      return "D";
424
    if (type.equals(void.class))
425
      return "V";
426
    else if (type.isArray())
427
      {
428
        StringBuffer l = new StringBuffer("[");
429
        Class component = type.getComponentType();
430
 
431
        while (component.isArray())
432
          {
433
            l.append('[');
434
            component = component.getComponentType();
435
          }
436
 
437
        l.append('L');
438
        l.append(component.getName().replace('.', '/'));
439
        l.append(';');
440
        return l.toString();
441
      }
442
    else
443
      return "L" + type.getName().replace('.', '/') + ';';
444
  }
445
 
446
  public static Field[] getWritableFields(Class c)
447
  {
448
    TreeSet set = new TreeSet(new Comparator()
449
    {
450
      public int compare(Object a, Object b)
451
      {
452
        return ((Field) a).getName().compareTo(((Field) b).getName());
453
      }
454
    });
455
 
456
    while (!c.equals(Object.class))
457
      {
458
        Field[] f = c.getDeclaredFields();
459
        for (int i = 0; i < f.length; i++)
460
          {
461
            if ((f[i].getModifiers() & NON_WRITABLE) == 0)
462
              {
463
                f[i].setAccessible(true);
464
                set.add(f[i]);
465
              }
466
          }
467
        c = c.getSuperclass();
468
      }
469
 
470
    Field[] r = new Field[set.size()];
471
    int p = 0;
472
    Iterator it = set.iterator();
473
    while (it.hasNext())
474
      {
475
        r[p++] = (Field) it.next();
476
      }
477
    return r;
478
  }
479
 
480
  /**
481
   * The method is called for Remotes that are not Stubs. It is assumed, that
482
   * the Remote is an implementation. The method searches for the suitable tie
483
   * and, if found, exports it by creating and connecting the stub. Such export
484
   * is supported since jdk 1.5.
485
   */
486
  void exportTie(org.omg.CORBA_2_3.portable.OutputStream output,
487
    Object implementation, Class interfaceClass)
488
  {
489
    try
490
      {
491
        // Remote, but non - stub class (implementation)
492
        // must be replaced by stub.
493
        Tie t = Util.getTie((Remote) implementation);
494
        if (t instanceof Servant)
495
          {
496
            POA rootPoa = POAHelper.narrow(output.orb().resolve_initial_references(
497
              "RootPOA"));
498
            org.omg.CORBA.Object co = rootPoa.servant_to_reference((Servant) t);
499
            Stub stub = (Stub) PortableRemoteObject.narrow(co, interfaceClass);
500
            writeRemoteObject(output, stub);
501
 
502
            if (rootPoa.the_POAManager().get_state().value() == State._HOLDING)
503
              rootPoa.the_POAManager().activate();
504
          }
505
        else if (t instanceof org.omg.CORBA.Object)
506
          {
507
            org.omg.CORBA.Object co = (org.omg.CORBA.Object) t;
508
            output.orb().connect(co);
509
 
510
            Stub stub = (Stub) PortableRemoteObject.narrow(co, interfaceClass);
511
            writeRemoteObject(output, stub);
512
          }
513
      }
514
    catch (Exception ex)
515
      {
516
        MARSHAL m = new MARSHAL("Unable to export " + implementation);
517
        m.minor = Minor.TargetConversion;
518
        m.initCause(ex);
519
        throw m;
520
      }
521
  }
522
 
523
  /**
524
   * Start the ORB, if it is not already runnning.
525
   */
526
  void ensureOrbRunning(org.omg.CORBA_2_3.portable.OutputStream output)
527
  {
528
    // Ensure ORB is running.
529
    if (output.orb() instanceof OrbFunctional)
530
      {
531
        ((OrbFunctional) output.orb()).ensureRunning();
532
      }
533
  }
534
 
535
  /**
536
   * Write data to the CORBA output stream. Writes the object contents only; the
537
   * header must be already written. For object, containing objects, may be
538
   * called recursively.
539
   *
540
   * @param an_output a stream to write to, must be
541
   * org.omg.CORBA_2_3.portable.OutputStream
542
   * @param object an object to write.
543
   */
544
  public void writeRemoteObject(OutputStream an_output, Object object)
545
  {
546
    org.omg.CORBA_2_3.portable.OutputStream output = (org.omg.CORBA_2_3.portable.OutputStream) an_output;
547
 
548
    if (isTieRequired(object))
549
      {
550
        // Find the interface that is implemented by the object and extends
551
        // Remote.
552
        Class fc = getExportedInterface(object);
553
        exportTie(output, object, fc);
554
      }
555
    else if (object instanceof org.omg.CORBA.Object)
556
      {
557
        ensureOrbRunning(output);
558
        an_output.write_Object((org.omg.CORBA.Object) object);
559
      }
560
    else if (object != null && object instanceof Serializable)
561
      writeFields(an_output, (Serializable) object);
562
  }
563
 
564
  /**
565
   * Write data to the CORBA output stream. Writes the object contents only; the
566
   * header must be already written. For object, containing objects, may be
567
   * called recursively.
568
   *
569
   * @param an_output a stream to write to, must be
570
   * org.omg.CORBA_2_3.portable.OutputStream
571
   * @param object an object to write.
572
   */
573
  public void writeValue(OutputStream an_output, Serializable object)
574
  {
575
    org.omg.CORBA_2_3.portable.OutputStream output = (org.omg.CORBA_2_3.portable.OutputStream) an_output;
576
 
577
    if (isTieRequired(object))
578
      {
579
        // Find the interface that is implemented by the object and extends
580
        // Remote.
581
        Class fc = getExportedInterface(object);
582
        exportTie(output, object, fc);
583
      }
584
    else if (object instanceof org.omg.CORBA.Object)
585
      {
586
        ensureOrbRunning(output);
587
        an_output.write_Object((org.omg.CORBA.Object) object);
588
      }
589
    else if (object instanceof Externalizable)
590
      {
591
        try
592
          {
593
            ObjectOutputStream stream = new CorbaOutput(output, object,
594
              this);
595
            stream.write(VERSION);
596
            ((Externalizable) object).writeExternal(stream);
597
          }
598
        catch (Exception ex)
599
          {
600
            MARSHAL m = new MARSHAL("writeExternal failed");
601
            m.minor = Minor.Value;
602
            m.initCause(ex);
603
            throw m;
604
          }
605
      }
606
    else if (object instanceof Serializable)
607
      {
608
        Object mode = null;
609
        synchronized (io_format)
610
          {
611
            mode = io_format.get(object.getClass());
612
            if (mode == STANDARD)
613
              {
614
                writeFields(an_output, (Serializable) object);
615
                return;
616
              }
617
          }
618
        try
619
          {
620
            Method m = object.getClass().getDeclaredMethod("writeObject",
621
              WRITE_OBJECT_ARGS);
622
            m.setAccessible(true); // May be private.
623
 
624
            try
625
              {
626
                ObjectOutputStream stream = new CorbaOutput(output,
627
                  object, this);
628
 
629
                // Write version.
630
                stream.write(VERSION);
631
 
632
                if (mode == CUSTOM_DWO)
633
                  // Write true, supposing that the defaultWriteObject
634
                  // has been called.
635
                  stream.write(1);
636
                else if (mode == CUSTOM_NO_DWO)
637
                  // Write false (has not been called)
638
                  stream.write(0);
639
                else
640
                  {
641
                    // Measure.
642
                    DefaultWriteObjectTester tester = new DefaultWriteObjectTester(object);
643
                    m.invoke(object, new Object[] { tester });
644
 
645
                    synchronized (io_format)
646
                      {
647
                        io_format.put(object.getClass(),
648
                          tester.dwo_called ? CUSTOM_DWO : CUSTOM_NO_DWO);
649
                        stream.write(tester.dwo_called ? 1 : 0);
650
                      }
651
                  }
652
 
653
                m.invoke(object, new Object[] { stream });
654
                stream.flush();
655
              }
656
            catch (Exception ex)
657
              {
658
                MARSHAL mx = new MARSHAL(object.getClass().getName()
659
                  + ".writeObject failed");
660
                mx.initCause(ex);
661
                throw mx;
662
              }
663
          }
664
        catch (NoSuchMethodException e)
665
          {
666
            // Write in a standard way.
667
            writeFields(an_output, (Serializable) object);
668
            synchronized (io_format)
669
              {
670
                io_format.put(object.getClass(), STANDARD);
671
              }
672
          }
673
      }
674
  }
675
 
676
  /**
677
   * Read data from the CDR input stream. Reads the object contents only; the
678
   * header must be already read (the repository id or ids ara passed). For
679
   * object, containing objects, may be called recursively.
680
   *
681
   * @param an_input the stream to read from, must be
682
   * org.omg.CORBA_2_3.portable.InputStream
683
   * @param object the instance of the object being read.
684
   * @param id the repository Id from the stream in the case when single id was
685
   * specified.
686
   * @param ids the repository Ids from the stream in the case when multiple ids
687
   * were specified.
688
   * @param codebase the codebase, if it was included in the header of the value
689
   * type. Null if not codebase was included.
690
   *
691
   * @return the object, extracted from the stream.
692
   */
693
  /**
694
   * Read value from the input stream in the case when the value is not
695
   * Streamable or CustomMarshalled.
696
   */
697
  public Serializable readValue(InputStream in, int offset, Class clz,
698
    String repositoryID, RunTime sender)
699
  {
700
    if (in instanceof HeadlessInput)
701
      ((HeadlessInput) in).subsequentCalls = true;
702
 
703
    gnuRuntime g;
704
    Serializable object = null;
705
 
706
    try
707
      {
708
        g = (gnuRuntime) sender;
709
        object = g.target;
710
      }
711
    catch (ClassCastException e)
712
      {
713
        // Working with the other CORBA implementation.
714
        g = null;
715
      }
716
 
717
    org.omg.CORBA_2_3.portable.InputStream input = (org.omg.CORBA_2_3.portable.InputStream) in;
718
 
719
    if (Remote.class.isAssignableFrom(clz)
720
      || ValueBase.class.isAssignableFrom(clz))
721
      {
722
        // Interface is narrowed into Stub.
723
        if (clz.isInterface())
724
          try
725
            {
726
              clz = Util.loadClass(
727
                PortableRemoteObjectDelegateImpl.getStubClassName(clz.getName()),
728
                null, clz.getClassLoader());
729
            }
730
          catch (ClassNotFoundException e)
731
            {
732
              MARSHAL m = new MARSHAL("Cannot get stub from interface "
733
                + clz.getClass().getName());
734
              m.minor = Minor.TargetConversion;
735
              m.initCause(e);
736
              throw m;
737
            }
738
 
739
        // Remote needs special handling.
740
        if (ObjectImpl.class.isAssignableFrom(clz))
741
          {
742
            // First read CORBA object reference.
743
            Object ro = input.read_Object();
744
 
745
            ObjectImpl obj = (ObjectImpl) ro;
746
            if (obj == null)
747
              return null;
748
 
749
            Delegate delegate = obj._get_delegate();
750
            object = instantiate(offset, clz, g);
751
            ((ObjectImpl) object)._set_delegate(delegate);
752
          }
753
        // The object - specific data follows.
754
      }
755
    else if (org.omg.CORBA.Object.class.isAssignableFrom(clz))
756
      object = (Serializable) input.read_Object();
757
 
758
    if (object == null)
759
      object = instantiate(offset, clz, g);
760
 
761
    // The sentence below prevents attempt to read the internal fields of the
762
    // ObjectImpl (or RMI Stub) that might follow the object definition.
763
    // Sun's jre 1.5 does not write this information. The stubs, generated
764
    // by rmic, does not contain such fields.
765
    if (object instanceof ObjectImpl)
766
      return object;
767
 
768
    if (object instanceof Externalizable)
769
      {
770
        try
771
          {
772
            CorbaInput stream = new CorbaInput(input, object, this,
773
              offset, repositoryID, g);
774
 
775
            byte version = stream.readByte();
776
            if (version != 1)
777
              throw new MARSHAL("Unsuported RMI-IIOP version " + version);
778
 
779
            ((Externalizable) object).readExternal(stream);
780
          }
781
        catch (Exception ex)
782
          {
783
            MARSHAL m = new MARSHAL("readExternal failed");
784
            m.initCause(ex);
785
            throw m;
786
          }
787
      }
788
    else
789
      {
790
        Object mode = null;
791
        synchronized (io_format)
792
          {
793
            mode = io_format.get(object.getClass());
794
          }
795
 
796
        if (mode == STANDARD)
797
          {
798
            readFields(offset, repositoryID, object, input, g);
799
          }
800
        else
801
          {
802
            try
803
              {
804
                Method m = object.getClass().getDeclaredMethod("readObject",
805
                  READ_OBJECT_ARGS);
806
                try
807
                  {
808
                    m.setAccessible(true); // May be private.
809
 
810
                    CorbaInput stream = new CorbaInput(input,
811
                      object, this, offset, repositoryID, g);
812
 
813
                    byte version = stream.readByte();
814
                    if (version != 1)
815
                      throw new MARSHAL("Unsuported RMI-IIOP version "
816
                        + version);
817
 
818
                    // This would indicate is defaultWriteObject has been
819
                    // called,
820
                    // but the readObject method normally takes care about this.
821
                    boolean dwo = stream.readByte() != 0;
822
 
823
                    m.invoke(object, new Object[] { stream });
824
                    synchronized (io_format)
825
                      {
826
                        io_format.put(object.getClass(), dwo ? CUSTOM_DWO
827
                          : CUSTOM_NO_DWO);
828
                      }
829
                  }
830
                catch (Exception ex)
831
                  {
832
                    ex.printStackTrace();
833
                    MARSHAL mx = new MARSHAL(object.getClass().getName()
834
                      + ".readObject failed");
835
                    mx.initCause(ex);
836
                    throw mx;
837
                  }
838
              }
839
            catch (NoSuchMethodException e)
840
              {
841
                // Read in a standard way.
842
                synchronized (io_format)
843
                  {
844
                    io_format.put(object.getClass(), STANDARD);
845
                    readFields(offset, repositoryID, object, input, g);
846
                  }
847
              }
848
          }
849
      }
850
    return object;
851
  }
852
 
853
  /**
854
   * Create an instance.
855
   */
856
  Serializable instantiate(int offset, Class clz, gnuRuntime g)
857
    throws MARSHAL
858
  {
859
    Serializable object;
860
    try
861
      {
862
        object = (Serializable) Vio.instantiateAnyWay(clz);
863
        g.objectWritten(object, offset);
864
      }
865
    catch (Exception e)
866
      {
867
        MARSHAL m = new MARSHAL("Unable to instantiate " + clz);
868
        m.minor = Minor.Instantiation;
869
        m.initCause(e);
870
        throw m;
871
      }
872
    return object;
873
  }
874
 
875
  /**
876
   * Read fields of the object.
877
   */
878
  void readFields(int offset, String repositoryID, Serializable object,
879
    org.omg.CORBA_2_3.portable.InputStream input, gnuRuntime r)
880
    throws MARSHAL
881
  {
882
    Field f = null;
883
    Class o_class = object.getClass();
884
 
885
    try
886
      {
887
        // The returned field array must already be in canonical order.
888
        Field[] fields = getWritableFields(o_class);
889
 
890
        Class fc;
891
 
892
        for (int i = 0; i < fields.length; i++)
893
          {
894
            // Full value type header expected ahead.
895
            if (input instanceof HeadlessInput)
896
              ((HeadlessInput) input).subsequentCalls = true;
897
 
898
            f = fields[i];
899
            fc = f.getType();
900
 
901
            Object v;
902
 
903
            if (fc == String.class)
904
              {
905
                v = input.read_value(wStringValueHelper);
906
              }
907
            else if (fc == int.class)
908
              v = new Integer(input.read_long());
909
            else if (fc == long.class)
910
              v = new Long(input.read_longlong());
911
            else if (fc == double.class)
912
              v = new Double(input.read_double());
913
            else if (fc == float.class)
914
              v = new Float(input.read_float());
915
            else if (fc == boolean.class)
916
              v = input.read_boolean() ? Boolean.TRUE : Boolean.FALSE;
917
            else if (fc == short.class)
918
              v = new Short(input.read_short());
919
            else if (fc == byte.class)
920
              v = new Byte(input.read_octet());
921
            else if (fc == char.class)
922
              v = new Character(input.read_char());
923
            else if (org.omg.CORBA.Object.class.isAssignableFrom(fc)
924
              || Remote.class.isAssignableFrom(fc))
925
              {
926
                v = readValue(input, offset, fc, null, r);
927
              }
928
            else
929
              {
930
                v = Vio.read(input, fc);
931
              }
932
 
933
            f.set(object, v);
934
          }
935
      }
936
    catch (Exception ex)
937
      {
938
        MARSHAL m = new MARSHAL("Cannot read " + o_class.getName() + " field "
939
          + f);
940
        m.initCause(ex);
941
        m.minor = Minor.ValueFields;
942
        throw m;
943
      }
944
  }
945
 
946
}

powered by: WebSVN 2.1.0

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