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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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