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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [java/] [rmi/] [server/] [UnicastServerRef.java] - Blame information for rev 775

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* UnicastServerRef.java --
2
   Copyright (c) 1996, 1997, 1998, 1999, 2002, 2003, 2004, 2006
3
   Free Software Foundation, Inc.
4
 
5
This file is part of GNU Classpath.
6
 
7
GNU Classpath is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2, or (at your option)
10
any later version.
11
 
12
GNU Classpath is distributed in the hope that it will be useful, but
13
WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GNU Classpath; see the file COPYING.  If not, write to the
19
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20
02110-1301 USA.
21
 
22
Linking this library statically or dynamically with other modules is
23
making a combined work based on this library.  Thus, the terms and
24
conditions of the GNU General Public License cover the whole
25
combination.
26
 
27
As a special exception, the copyright holders of this library give you
28
permission to link this library with independent modules to produce an
29
executable, regardless of the license terms of these independent
30
modules, and to copy and distribute the resulting executable under
31
terms of your choice, provided that you also meet, for each linked
32
independent module, the terms and conditions of the license of that
33
module.  An independent module is a module which is not derived from
34
or based on this library.  If you modify this library, you may extend
35
this exception to your version of the library, but you are not
36
obligated to do so.  If you do not wish to do so, delete this
37
exception statement from your version. */
38
 
39
 
40
package gnu.java.rmi.server;
41
 
42
import java.io.ObjectInputStream;
43
import java.lang.reflect.Constructor;
44
import java.lang.reflect.InvocationTargetException;
45
import java.lang.reflect.Method;
46
import java.lang.reflect.Proxy;
47
import java.rmi.Remote;
48
import java.rmi.RemoteException;
49
import java.rmi.server.ObjID;
50
import java.rmi.server.RMIServerSocketFactory;
51
import java.rmi.server.RemoteObjectInvocationHandler;
52
import java.rmi.server.RemoteRef;
53
import java.rmi.server.RemoteServer;
54
import java.rmi.server.RemoteStub;
55
import java.rmi.server.ServerNotActiveException;
56
import java.rmi.server.Skeleton;
57
import java.util.HashSet;
58
import java.util.Hashtable;
59
import java.util.Iterator;
60
 
61
/**
62
 * This class connects the local, remotely available (exported) object to
63
 * the local RMI server that accepts the remote calls.
64
 */
65
public class UnicastServerRef
66
    extends UnicastRef
67
{
68
 
69
  /**
70
   * Use GNU Classpath v 0.20 SVUID for interoperability
71
   */
72
  private static final long serialVersionUID = - 5585608108300801246L;
73
 
74
  /**
75
   * The class array, defining parameters of the jdk 1.2 RMI stub constructor.
76
   */
77
  private static final Class[] stubprototype = new Class[] { RemoteRef.class };
78
 
79
  /**
80
   * The exported remote object itself.
81
   */
82
  Remote myself; // save the remote object itself
83
 
84
  /**
85
   * The skeleton (if any), associated with the exported remote object.
86
   */
87
  protected Skeleton skel;
88
 
89
  /**
90
   * The stub, associated with the exported remote object (may be proxy class).
91
   */
92
  protected Remote stub;
93
 
94
  /**
95
   * The method table (RMI hash code to method) of the methods of the
96
   * exported object.
97
   */
98
  protected Hashtable methods = new Hashtable();
99
 
100
  /**
101
   * Used by serialization.
102
   */
103
  UnicastServerRef()
104
  {
105
  }
106
 
107
  public UnicastServerRef(ObjID id, int port, RMIServerSocketFactory ssf)
108
      throws RemoteException
109
  {
110
    super(id);
111
    manager = UnicastConnectionManager.getInstance(port, ssf);
112
  }
113
 
114
  /**
115
   * Export the object and return its remote stub. The method tries to locate
116
   * existing stubs and skeletons. If this fails, the method instantiates the
117
   * proxy stub class.
118
   *
119
   * Stubs and skeletons are always ignored (even if present) if the
120
   * java.rmi.server.ignoreStubClasses property is set to true.
121
   *
122
   * @param obj the object being exported.
123
   * @return the stub (existing class or proxy) of the exported object.
124
   * @throws RemoteException if the export failed due any reason
125
   */
126
  public Remote exportObject(Remote obj) throws RemoteException
127
  {
128
    if (myself == null)
129
      {
130
        myself = obj;
131
        // Save it to server manager, to let client calls in the same VM to
132
        // issue local call
133
        manager.serverobj = obj;
134
 
135
        String ignoreStubs;
136
 
137
        ClassLoader loader =obj.getClass().getClassLoader();
138
 
139
        // Stubs are always searched for the bootstrap classes that may have
140
        // obsolete pattern and may still need also skeletons.
141
        if (loader==null)
142
          ignoreStubs = "false";
143
        else
144
          ignoreStubs = System.getProperty("java.rmi.server.ignoreStubClasses",
145
                                           "false");
146
 
147
        if (! ignoreStubs.equals("true"))
148
          {
149
            // Find and install the stub
150
            Class cls = obj.getClass();
151
 
152
            // where ist the _Stub? (check superclasses also)
153
            Class expCls = findStubSkelClass(cls);
154
 
155
            if (expCls != null)
156
              {
157
                stub = (RemoteStub) getHelperClass(expCls, "_Stub");
158
                // Find and install the skeleton (if there is one)
159
                skel = (Skeleton) getHelperClass(expCls, "_Skel");
160
              }
161
          }
162
 
163
        if (stub == null)
164
          stub = createProxyStub(obj.getClass(), this);
165
 
166
        // Build hash of methods which may be called.
167
        buildMethodHash(obj.getClass(), true);
168
 
169
        // Export it.
170
        UnicastServer.exportObject(this);
171
      }
172
 
173
    return stub;
174
  }
175
 
176
  /**
177
   * Get the stub (actual class or proxy) of the exported remote object.
178
   *
179
   * @return the remote stub (null if exportObject has not been called).
180
   */
181
  public Remote getStub()
182
  {
183
    return stub;
184
  }
185
 
186
  /**
187
   * Unexport the object (remove methods from the method hashcode table
188
   * and call UnicastServer.unexportObject.
189
   *
190
   * @param obj the object being unexported
191
   * @param force passed to the UnicastServer.unexportObject.
192
   * @return value, returned by the UnicastServer.unexportObject.
193
   */
194
  public boolean unexportObject(Remote obj, boolean force)
195
  {
196
    // Remove all hashes of methods which may be called.
197
    buildMethodHash(obj.getClass(), false);
198
    return UnicastServer.unexportObject(this, force);
199
  }
200
 
201
  /**
202
   * Return the class in the hierarchy for that the stub class is defined.
203
   * The Subs/Skels might not there for the actual class, but maybe for one of
204
   * the superclasses.
205
   *
206
   * @return the class having stub defined, null if none.
207
   */
208
  protected Class findStubSkelClass(Class startCls)
209
  {
210
    Class cls = startCls;
211
 
212
    while (true)
213
      {
214
        try
215
          {
216
            String stubClassname = cls.getName() + "_Stub";
217
            ClassLoader cl = cls.getClassLoader();
218
            Class scls = cl == null ? Class.forName(stubClassname)
219
                                   : cl.loadClass(stubClassname);
220
            return cls; // found it
221
          }
222
        catch (ClassNotFoundException e)
223
          {
224
            Class superCls = cls.getSuperclass();
225
            if (superCls == null
226
                || superCls == java.rmi.server.UnicastRemoteObject.class)
227
              {
228
                return null;
229
              }
230
            cls = superCls;
231
          }
232
      }
233
  }
234
 
235
  /**
236
   * Get the helper (assisting) class with the given type.
237
   *
238
   * @param cls the class, for that the helper class is requested. This class
239
   * and the requested helper class must share the same class loader.
240
   *
241
   * @param type the type of the assisting helper. The only currently supported
242
   * non deprecated value is "_Stub" (load jdk 1.1 or 1.2 RMI stub). Another
243
   * (deprecated) value is "_Skel" (load skeleton).
244
   *
245
   * @return the instantiated instance of the helper class or null if the
246
   * helper class cannot be found or instantiated.
247
   */
248
  protected Object getHelperClass(Class cls, String type)
249
  {
250
    try
251
      {
252
        String classname = cls.getName();
253
        ClassLoader cl = cls.getClassLoader();
254
        Class scls = cl == null ? Class.forName(classname + type)
255
                               : cl.loadClass(classname + type);
256
        if (type.equals("_Stub"))
257
          {
258
            try
259
              {
260
                // JDK 1.2 stubs
261
                Constructor con = scls.getConstructor(stubprototype);
262
                return (con.newInstance(new Object[] { this }));
263
              }
264
            catch (NoSuchMethodException e)
265
              {
266
              }
267
            catch (InstantiationException e)
268
              {
269
              }
270
            catch (IllegalAccessException e)
271
              {
272
              }
273
            catch (IllegalArgumentException e)
274
              {
275
              }
276
            catch (InvocationTargetException e)
277
              {
278
              }
279
            // JDK 1.1 stubs
280
            RemoteStub stub = (RemoteStub) scls.newInstance();
281
            UnicastRemoteStub.setStubRef(stub, this);
282
            return (stub);
283
          }
284
        else
285
          {
286
            // JDK 1.1 skel
287
            return (scls.newInstance());
288
          }
289
      }
290
    catch (ClassNotFoundException e)
291
      {
292
      }
293
    catch (InstantiationException e)
294
      {
295
      }
296
    catch (IllegalAccessException e)
297
      {
298
      }
299
    return (null);
300
  }
301
 
302
  public String getClientHost() throws ServerNotActiveException
303
  {
304
    return RemoteServer.getClientHost();
305
  }
306
 
307
  /**
308
   * Build the method has code table and put it into {@link #methods}
309
   * (mapping RMI hashcode tos method). The same method is used to remove
310
   * the table.
311
   *
312
   * @param cls the class for that the method table is built.
313
   * @param build if true, the class methods are added to the table. If
314
   * false, they are removed from the table.
315
   */
316
  protected void buildMethodHash(Class cls, boolean build)
317
  {
318
    Method[] meths = cls.getMethods();
319
    for (int i = 0; i < meths.length; i++)
320
      {
321
        /* Don't need to include any java.xxx related stuff */
322
        if (meths[i].getDeclaringClass().getName().startsWith("java."))
323
          {
324
            continue;
325
          }
326
        long hash = RMIHashes.getMethodHash(meths[i]);
327
        if (build)
328
          methods.put(new Long(hash), meths[i]);
329
        else
330
          methods.remove(new Long(hash));
331
        // System.out.println("meth = " + meths[i] + ", hash = " + hash);
332
      }
333
  }
334
 
335
  Class getMethodReturnType(int method, long hash) throws Exception
336
  {
337
    if (method == - 1)
338
      {
339
        Method meth = (Method) methods.get(new Long(hash));
340
        return meth.getReturnType();
341
      }
342
    else
343
      return null;
344
  }
345
 
346
  /**
347
   * This method is called from the {@link UnicastServer#incomingMessageCall}
348
   * to deliver the remote call to this object.
349
   */
350
  public Object incomingMessageCall(UnicastConnection conn, int method,
351
                                    long hash) throws Exception
352
  {
353
    // System.out.println("method = " + method + ", hash = " + hash);
354
    // If method is -1 then this is JDK 1.2 RMI - so use the hash
355
    // to locate the method
356
    if (method == - 1)
357
      {
358
        Method meth = (Method) methods.get(new Long(hash));
359
        // System.out.println("class = " + myself.getClass() + ", meth = " +
360
        // meth);
361
        if (meth == null)
362
          {
363
            throw new NoSuchMethodException(
364
              myself.getClass().getName()+" hash "+hash);
365
          }
366
 
367
        ObjectInputStream in = conn.getObjectInputStream();
368
        int nrargs = meth.getParameterTypes().length;
369
        Object[] args = new Object[nrargs];
370
        for (int i = 0; i < nrargs; i++)
371
          {
372
            /**
373
             * For debugging purposes - we don't handle CodeBases quite right so
374
             * we don't always find the stubs. This lets us know that.
375
             */
376
            try
377
              {
378
                // need to handle primitive types
379
                args[i] = ((RMIObjectInputStream) in)
380
                  .readValue(meth.getParameterTypes()[i]);
381
 
382
              }
383
            catch (Exception t)
384
              {
385
                t.printStackTrace();
386
                throw t;
387
              }
388
          }
389
        //We must reinterpret the exception thrown by meth.invoke()
390
        //return (meth.invoke(myself, args));
391
        Object ret = null;
392
        try
393
          {
394
            ret = meth.invoke(myself, args);
395
          }
396
        catch (InvocationTargetException e)
397
          {
398
            Throwable cause = e.getTargetException();
399
            if (cause instanceof Exception)
400
              {
401
                throw (Exception) cause;
402
              }
403
            else if (cause instanceof Error)
404
              {
405
                throw (Error) cause;
406
              }
407
            else
408
              {
409
                throw new Error(
410
                  "The remote method threw a java.lang.Throwable that"+
411
                  " is neither java.lang.Exception nor java.lang.Error.",
412
                  e);
413
              }
414
          }
415
        return ret;
416
      }
417
    // Otherwise this is JDK 1.1 style RMI - we find the skeleton
418
    // and invoke it using the method number.  We wrap up our
419
    // connection system in a UnicastRemoteCall so it appears in a
420
    // way the Skeleton can handle.
421
    else
422
      {
423
        if (skel == null)
424
          throw new NoSuchMethodException("JDK 1.1 call - Skeleton required");
425
 
426
        UnicastRemoteCall call = new UnicastRemoteCall(conn);
427
        skel.dispatch(myself, call, method, hash);
428
        if (! call.isReturnValue())
429
          return RMIVoidValue.INSTANCE;
430
        else
431
          return (call.returnValue());
432
      }
433
  }
434
 
435
  /**
436
   * Create the 1.2 proxy stub in the case when the pre-generated stub is not
437
   * available of the system is explicitly instructed to use proxy stubs.
438
   *
439
   * @param stubFor the class for that the proxy class must be constructed.
440
   * @param reference the remote reference, used to find the given object
441
   *
442
   * @return the applicable proxy stub.
443
   *
444
   * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
445
   */
446
  Remote createProxyStub(Class stubFor, RemoteRef reference)
447
  {
448
    // Collect all interfaces, implemented by stubFor and derived from
449
    // Remote (also Remote itself):
450
    HashSet interfaces = new HashSet();
451
    Class c = stubFor;
452
    Class[] intfs;
453
 
454
    while (c != null)
455
      {
456
        intfs = c.getInterfaces();
457
        for (int i = 0; i < intfs.length; i++)
458
          {
459
            if (Remote.class.isAssignableFrom(intfs[i]))
460
              interfaces.add(intfs[i]);
461
          }
462
        c = c.getSuperclass();
463
      }
464
 
465
    intfs = new Class[interfaces.size()];
466
    Iterator it = interfaces.iterator();
467
 
468
    for (int i = 0; i < intfs.length; i++)
469
      intfs[i] = (Class) it.next();
470
 
471
    RemoteObjectInvocationHandler handler =
472
      new RemoteObjectInvocationHandler(reference);
473
 
474
    Object proxy =
475
      Proxy.newProxyInstance(stubFor.getClassLoader(), intfs, handler);
476
 
477
    return (Remote) proxy;
478
  }
479
 
480
 
481
}

powered by: WebSVN 2.1.0

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