Source for gnu.java.rmi.server.UnicastRemoteCall

   1: /* UnicastRemoteCall.java
   2:    Copyright (c) 1996, 1997, 1998, 1999, 2002, 2004, 2005
   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.DataInputStream;
  43: import java.io.DataOutputStream;
  44: import java.io.IOException;
  45: import java.io.ObjectInput;
  46: import java.io.ObjectOutput;
  47: import java.io.StreamCorruptedException;
  48: import java.rmi.MarshalException;
  49: import java.rmi.RemoteException;
  50: import java.rmi.UnmarshalException;
  51: import java.rmi.server.ObjID;
  52: import java.rmi.server.RemoteCall;
  53: import java.rmi.server.UID;
  54: import java.util.Vector;
  55: 
  56: public class UnicastRemoteCall
  57:         implements RemoteCall, ProtocolConstants
  58: {
  59: 
  60:   private UnicastConnection conn;
  61:   private Object result;
  62:   private Object object;
  63:   private int opnum;
  64:   private long hash;
  65:   // These are package-private due to inner class access.
  66:   Vector vec;
  67:   int ptr;
  68:   private ObjID objid;
  69: 
  70:   private ObjectOutput oout;
  71:   private ObjectInput oin;
  72: 
  73:   /**
  74:    * Incoming call.
  75:    */
  76:   UnicastRemoteCall(UnicastConnection conn)
  77:   {
  78:     this.conn = conn;
  79:   }
  80: 
  81:   /**
  82:    * Outgoing call.
  83:    */
  84:   UnicastRemoteCall(UnicastConnection conn, ObjID objid, int opnum, long hash)
  85:     throws RemoteException
  86:   {
  87:     this.conn = conn;
  88:     this.opnum = opnum;
  89:     this.hash = hash;
  90:     this.objid = objid;
  91:   }
  92: 
  93:   UnicastConnection getConnection()
  94:   {
  95:     return conn;
  96:   }
  97: 
  98:   public ObjectOutput getOutputStream() throws IOException
  99:   {
 100:     if (vec == null)
 101:       vec = new Vector();
 102:     return (new DummyObjectOutputStream());
 103:   }
 104: 
 105:   public void releaseOutputStream() throws IOException
 106:   {
 107:     if (vec != null)
 108:       {
 109:         oout = conn.getObjectOutputStream();
 110: 
 111:         for (int i = 0; i < vec.size(); i += 2)
 112:           {
 113:             boolean primitive = ((Boolean)vec.elementAt(i)).booleanValue();
 114:             Object data = vec.elementAt(i+1);
 115: 
 116:             // No type, this is
 117:             if (!primitive)
 118:               oout.writeObject(data);
 119:             else
 120:               {
 121:                 if (data instanceof Boolean)
 122:                   oout.writeBoolean(((Boolean)data).booleanValue());
 123:                 else if (data instanceof Character)
 124:                   oout.writeChar(((Character)data).charValue());
 125:                 else if (data instanceof Byte)
 126:                   oout.writeByte(((Byte)data).byteValue());
 127:                 else if (data instanceof Short)
 128:                   oout.writeShort(((Short)data).shortValue());
 129:                 else if (data instanceof Integer)
 130:                   oout.writeInt(((Integer)data).intValue());
 131:                 else if (data instanceof Long)
 132:                   oout.writeLong(((Long)data).longValue());
 133:               }
 134:           }
 135:         vec = null;
 136:       }
 137:     if(oout != null)
 138:       oout.flush();
 139:   }
 140: 
 141:   /**
 142:   *
 143:   * (re)starts ObjectInputStream
 144:   *
 145:   */
 146:   public ObjectInput startInputStream() throws IOException
 147:   {
 148:         if (conn != null) {
 149:                 return (oin = conn.startObjectInputStream());
 150:         } else {
 151:                 return getInputStream(); // dummy Input Stream
 152:         }
 153: 
 154:   }
 155: 
 156:   public ObjectInput getInputStream() throws IOException
 157:   {
 158:     if (conn != null)
 159:       {
 160:         if(oin == null)
 161:           return (oin = conn.getObjectInputStream());
 162:         else
 163:           return oin;
 164:       }
 165:     else
 166:       {
 167:         ptr = 0;
 168:         return (new DummyObjectInputStream());
 169:       }
 170:   }
 171: 
 172:   public void releaseInputStream() throws IOException
 173:   {
 174:     // Does nothing.
 175:   }
 176: 
 177:   public ObjectOutput getResultStream(boolean success)
 178:     throws IOException, StreamCorruptedException
 179:   {
 180:     vec = new Vector();
 181:     return new DummyObjectOutputStream();
 182:   }
 183: 
 184:   public void executeCall() throws Exception
 185:   {
 186:     byte returncode;
 187:     ObjectInput oin;
 188: 
 189:     // signal the call when constructing
 190:     try
 191:       {
 192:         DataOutputStream dout = conn.getDataOutputStream();
 193:         dout.write(MESSAGE_CALL);
 194: 
 195:         oout = conn.startObjectOutputStream(); // (re)start ObjectOutputStream
 196:         objid.write(oout);
 197:         oout.writeInt(opnum);
 198:         oout.writeLong(hash);
 199:       }
 200:     catch(IOException ex)
 201:       {
 202:         throw new MarshalException("Try to write header but failed.", ex);
 203:       }
 204: 
 205:     try
 206:       {
 207:         releaseOutputStream();
 208:         DataInputStream din = conn.getDataInputStream();
 209:         if (din.readByte() != MESSAGE_CALL_ACK)
 210:             throw new RemoteException("Call not acked");
 211: 
 212:         oin = startInputStream();
 213:         returncode = oin.readByte();
 214:         UID.read(oin);
 215:       }
 216:     catch(IOException ex)
 217:       {
 218:         throw new UnmarshalException("Try to read header but failed:", ex);
 219:       }
 220: 
 221:     //check return code
 222:     switch(returncode)
 223:       {
 224:       case RETURN_ACK: //it's ok
 225:         return;
 226:       case RETURN_NACK:
 227:         Object returnobj;
 228:         try
 229:           {
 230:             returnobj = oin.readObject();
 231:           }
 232:         catch(Exception ex2)
 233:           {
 234:             throw new UnmarshalException
 235:               ("Try to read exception object but failed", ex2);
 236:           }
 237: 
 238:         if(!(returnobj instanceof Exception))
 239:           throw new UnmarshalException("Should be Exception type here: "
 240:                                        + returnobj);
 241:         throw (Exception)returnobj;
 242: 
 243:       default:
 244:         throw new UnmarshalException("Invalid return code");
 245:       }
 246:   }
 247: 
 248:   public void done() throws IOException
 249:   {
 250:     // conn.disconnect();
 251:   }
 252: 
 253:   boolean isReturnValue()
 254:   {
 255:     return vec.size() > 0;
 256:   }
 257: 
 258:   Object returnValue()
 259:   {
 260:     // This is not the first one (Boolean) but the second.
 261:     return vec.elementAt(1);
 262:   }
 263: 
 264:   Object[] getArguments()
 265:   {
 266:     return vec.toArray();
 267:   }
 268: 
 269:   Object getObject()
 270:   {
 271:     return object;
 272:   }
 273: 
 274:   int getOpnum()
 275:   {
 276:     return opnum;
 277:   }
 278: 
 279:   long getHash()
 280:   {
 281:     return hash;
 282:   }
 283: 
 284:   void setReturnValue(Object obj)
 285:   {
 286:     vec.removeAllElements();
 287:     vec.addElement(obj);
 288:   }
 289: 
 290:   /**
 291:    * Dummy object output class.
 292:    */
 293:   private class DummyObjectOutputStream implements ObjectOutput
 294:   {
 295:     /**
 296:      * Non-private constructor to reduce bytecode emitted.
 297:      */
 298:     DummyObjectOutputStream()
 299:     {
 300:     }
 301: 
 302:     public void writeBoolean(boolean v) throws IOException
 303:     {
 304:       vec.addElement(Boolean.TRUE);
 305:       vec.addElement(Boolean.valueOf(v));
 306:     }
 307: 
 308:     public void writeByte(int v) throws IOException
 309:     {
 310:       vec.addElement(Boolean.TRUE);
 311:       vec.addElement(new Byte((byte) v));
 312:     }
 313: 
 314:     public void writeChar(int v) throws IOException
 315:     {
 316:       vec.addElement(Boolean.TRUE);
 317:       vec.addElement(new Character((char) v));
 318:     }
 319: 
 320:     public void writeDouble(double v) throws IOException
 321:     {
 322:       vec.addElement(Boolean.TRUE);
 323:       vec.addElement(new Double(v));
 324:     }
 325: 
 326:     public void writeFloat(float v) throws IOException
 327:     {
 328:       vec.addElement(Boolean.TRUE);
 329:       vec.addElement(new Float(v));
 330:     }
 331: 
 332:     public void writeInt(int v) throws IOException
 333:     {
 334:       vec.addElement(Boolean.TRUE);
 335:       vec.addElement(new Integer(v));
 336:     }
 337: 
 338:     public void writeLong(long v) throws IOException
 339:     {
 340:       vec.addElement(Boolean.TRUE);
 341:       vec.addElement(new Long(v));
 342:     }
 343: 
 344:     public void writeShort(int v) throws IOException
 345:     {
 346:       vec.addElement(Boolean.TRUE);
 347:       vec.addElement(new Short((short) v));
 348:     }
 349: 
 350:     public void writeObject(Object obj) throws IOException
 351:     {
 352:       vec.addElement(Boolean.FALSE);
 353:       vec.addElement(obj);
 354:     }
 355: 
 356:     public void write(byte b[]) throws IOException
 357:     {
 358:       throw new IOException("not required");
 359:     }
 360: 
 361:     public void write(byte b[], int off, int len) throws IOException
 362:     {
 363:       throw new IOException("not required");
 364:     }
 365: 
 366:     public void write(int b) throws IOException
 367:     {
 368:       throw new IOException("not required");
 369:     }
 370: 
 371:     public void writeBytes(String s) throws IOException
 372:     {
 373:       throw new IOException("not required");
 374:     }
 375: 
 376:     public void writeChars(String s) throws IOException
 377:     {
 378:       throw new IOException("not required");
 379:     }
 380: 
 381:     public void writeUTF(String str) throws IOException
 382:     {
 383:       throw new IOException("not required");
 384:     }
 385: 
 386:     public void flush() throws IOException
 387:     {
 388:     }
 389: 
 390:     public void close() throws IOException
 391:     {
 392:     }
 393:   } // class DummyObjectOutputStream
 394: 
 395:   /**
 396:    * Dummy object input class.
 397:    */
 398:   private class DummyObjectInputStream implements ObjectInput
 399:   {
 400:     /**
 401:      * Non-private constructor to reduce bytecode emitted.
 402:      */
 403:     DummyObjectInputStream()
 404:     {
 405:     }
 406: 
 407:     public boolean readBoolean() throws IOException
 408:     {
 409:       Object obj = vec.elementAt(ptr++);
 410:       return ((Boolean) obj).booleanValue();
 411:     }
 412: 
 413:     public byte readByte() throws IOException
 414:     {
 415:       Object obj = vec.elementAt(ptr++);
 416:       return ((Byte) obj).byteValue();
 417:     }
 418: 
 419:     public char readChar() throws IOException
 420:     {
 421:       Object obj = vec.elementAt(ptr++);
 422:       return ((Character) obj).charValue();
 423:     }
 424: 
 425:     public double readDouble() throws IOException
 426:     {
 427:       Object obj = vec.elementAt(ptr++);
 428:       return ((Double) obj).doubleValue();
 429:     }
 430: 
 431:     public float readFloat() throws IOException
 432:     {
 433:       Object obj = vec.elementAt(ptr++);
 434:       return ((Float) obj).floatValue();
 435:     }
 436: 
 437:     public int readInt() throws IOException
 438:     {
 439:       Object obj = vec.elementAt(ptr++);
 440:       return ((Integer) obj).intValue();
 441:     }
 442: 
 443:     public long readLong() throws IOException
 444:     {
 445:       Object obj = vec.elementAt(ptr++);
 446:       return ((Long) obj).longValue();
 447:     }
 448: 
 449:     public short readShort() throws IOException
 450:     {
 451:       Object obj = vec.elementAt(ptr++);
 452:       return ((Short) obj).shortValue();
 453:     }
 454: 
 455:     public Object readObject() throws IOException
 456:     {
 457:       return vec.elementAt(ptr++);
 458:     }
 459: 
 460:     public int read(byte b[]) throws IOException
 461:     {
 462:       throw new IOException("not required");
 463:     }
 464: 
 465:     public int read(byte b[], int off, int len) throws IOException
 466:     {
 467:       throw new IOException("not required");
 468:     }
 469: 
 470:     public int read() throws IOException
 471:     {
 472:       throw new IOException("not required");
 473:     }
 474: 
 475:     public long skip(long n) throws IOException
 476:     {
 477:       throw new IOException("not required");
 478:     }
 479: 
 480:     public int available() throws IOException
 481:     {
 482:       throw new IOException("not required");
 483:     }
 484: 
 485:     public void readFully(byte b[]) throws IOException
 486:     {
 487:       throw new IOException("not required");
 488:     }
 489: 
 490:     public void readFully(byte b[], int off, int len) throws IOException
 491:     {
 492:       throw new IOException("not required");
 493:     }
 494: 
 495:     public String readLine() throws IOException
 496:     {
 497:       throw new IOException("not required");
 498:     }
 499: 
 500:     public String readUTF() throws IOException
 501:     {
 502:       throw new IOException("not required");
 503:     }
 504: 
 505:     public int readUnsignedByte() throws IOException
 506:     {
 507:       throw new IOException("not required");
 508:     }
 509: 
 510:     public int readUnsignedShort() throws IOException
 511:     {
 512:       throw new IOException("not required");
 513:     }
 514: 
 515:     public int skipBytes(int n) throws IOException
 516:     {
 517:       throw new IOException("not required");
 518:     }
 519: 
 520:     public void close() throws IOException
 521:     {
 522:     }
 523:   } // class DummyObjectInputStream
 524: 
 525: }