Source for gnu.javax.rmi.CORBA.StubDelegateImpl

   1: /* StubDelegateImpl.java --
   2:    Copyright (C) 2002, 2004, 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.ObjectCreator;
  42: import gnu.CORBA.Unexpected;
  43: import gnu.CORBA.CDR.BufferredCdrInput;
  44: import gnu.CORBA.CDR.BufferedCdrOutput;
  45: 
  46: import java.io.IOException;
  47: import java.io.ObjectInputStream;
  48: import java.io.ObjectOutputStream;
  49: import java.rmi.Remote;
  50: import java.rmi.RemoteException;
  51: 
  52: import javax.rmi.PortableRemoteObject;
  53: import javax.rmi.CORBA.Stub;
  54: import javax.rmi.CORBA.StubDelegate;
  55: import javax.rmi.CORBA.Tie;
  56: import javax.rmi.CORBA.Util;
  57: 
  58: import org.omg.CORBA.BAD_PARAM;
  59: import org.omg.CORBA.ORB;
  60: import org.omg.CORBA.portable.Delegate;
  61: import org.omg.CORBA.portable.ObjectImpl;
  62: import org.omg.PortableServer.POA;
  63: import org.omg.PortableServer.POAHelper;
  64: import org.omg.PortableServer.Servant;
  65: import org.omg.PortableServer.POAManagerPackage.State;
  66: 
  67: /**
  68:  * The default stub delegate.
  69:  *
  70:  * @author Wu Gansha (gansha.wu@intel.com) (stub)
  71:  * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) (implementation)
  72:  */
  73: public class StubDelegateImpl
  74:   implements StubDelegate
  75: {
  76:   /**
  77:    * <p>
  78:    * Finds the suitable {@link Tie} for this Stub and connects it to the given
  79:    * ORB. The tie is found by the name pattern. If the found tie is derived from
  80:    * {@link org.omg.CORBA.PortableServer.Servant}, it is connected to the root
  81:    * POA, also activating it (if not already active).
  82:    * </p>
  83:    * <p>
  84:    * This method does not allow to specify, to which POA the found Tie must be
  85:    * connected and requires to use the deprecated method {@link ORB#connect}.
  86:    * Many useful POA features remain unaccessible. A better alternative it might
  87:    * be to generate a {@link org.omg.CORBA.PortableServer.Servant} - derived Tie
  88:    * (-poa key in rmic) and connect it to POA in one of the many ways, listed in
  89:    * the description of the {@link orb.omg.PortableServer} package). The
  90:    * obtained CORBA object can be narrowed into stub using
  91:    * {@link PortableRemoteObject#narrow}.
  92:    * </p>
  93:    *
  94:    * @param orb the ORB where the Stub must be connected.
  95:    *
  96:    * @throws RemoteException if the stub is already connected to some other ORB.
  97:    * If the stub is already connected to the ORB that was passed as parameter,
  98:    * the method returns without action.
  99:    *
 100:    * @throws BAD_PARAM if the name of this stub does not match the stub name
 101:    * pattern, "_*_Stub" or if the Tie class, "_*Impl_Tie", does not exists or an
 102:    * instance of this class cannot be instantiated.
 103:    */
 104:   public void connect(Stub self, ORB orb)
 105:     throws RemoteException
 106:   {
 107:     connect(self, orb, null);
 108:   }
 109: 
 110:   /**
 111:    * Connect when the POA is specified.
 112:    */
 113:   public static void connect(Stub self, ORB orb, POA poa)
 114:     throws RemoteException
 115:   {
 116:     ORB oorb = null;
 117:     try
 118:       {
 119:         Delegate d = self._get_delegate();
 120:         if (d != null)
 121:           oorb = d.orb(self);
 122:       }
 123:     catch (Exception e)
 124:       {
 125:         // Failed to get Delegate or ORB.
 126:         // (possible ony for user-written Stubs).
 127:       }
 128: 
 129:     if (oorb != null)
 130:       {
 131:         if (!oorb.equals(orb))
 132:           throw new RemoteException("Stub " + self
 133:             + " is connected to another ORB, " + orb);
 134:         else
 135:           return;
 136:       }
 137: 
 138:     Tie t = null;
 139:     if (self instanceof Remote)
 140:       t = Util.getTie((Remote) self);
 141: 
 142:     // Find by name pattern.
 143:     if (t == null)
 144:       t = getTieFromStub(self);
 145: 
 146:     Delegate delegate;
 147: 
 148:     if (t instanceof Servant)
 149:       {
 150:         try
 151:           {
 152:             if (poa == null)
 153:               {
 154:                 poa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
 155:                 // Activate if not active.
 156:                 if (poa.the_POAManager().get_state().value() == State._HOLDING)
 157:                   poa.the_POAManager().activate();
 158:               }
 159: 
 160:             ObjectImpl obj = (ObjectImpl) poa.servant_to_reference((Servant) t);
 161:             delegate = obj._get_delegate();
 162:           }
 163:         catch (Exception ex)
 164:           {
 165:             throw new Unexpected(ex);
 166:           }
 167:       }
 168:     else if (t instanceof ObjectImpl)
 169:       {
 170:         ObjectImpl o = (ObjectImpl) t;
 171:         orb.connect(o);
 172:         delegate = o._get_delegate();
 173:       }
 174:     else
 175:       throw new BAD_PARAM("The Tie must be either Servant or ObjectImpl");
 176: 
 177:     self._set_delegate(delegate);
 178:   }
 179: 
 180:   /**
 181:    * Locate a tie class, appropriate to the given stub class, by the name
 182:    * pattern.
 183:    */
 184:   public static Tie getTieFromStub(java.lang.Object self)
 185:   {
 186:     Tie t;
 187:     String sn = self.getClass().getName();
 188:     if (!sn.endsWith("_Stub"))
 189:       throw new BAD_PARAM("The stub name, " + sn
 190:         + ", does not match _*_Stub pattern");
 191: 
 192:     String tn = sn.substring(0, sn.length() - "_Stub".length()) + "Impl_Tie";
 193:     Class tieClass = null;
 194: 
 195:     try
 196:       {
 197:         tieClass = ObjectCreator.forName(tn);
 198:         t = (Tie) tieClass.newInstance();
 199:         if (self instanceof Remote)
 200:           Util.registerTarget(t, (Remote) self);
 201:       }
 202:     catch (Exception e)
 203:       {
 204:         BAD_PARAM bad = new BAD_PARAM("Unable to instantiate '" + tn + "'");
 205:         bad.initCause(e);
 206:         throw bad;
 207:       }
 208:     return t;
 209:   }
 210: 
 211:   /**
 212:    * Compare two stubs for equality.
 213:    */
 214:   public boolean equals(Stub self, java.lang.Object obj)
 215:   {
 216:     if (obj instanceof ObjectImpl)
 217:       {
 218:         ObjectImpl other = (ObjectImpl) obj;
 219:         Delegate d1 = other._get_delegate();
 220:         Delegate d2 = self._get_delegate();
 221:         if (d1 == null || d2 == null)
 222:           return d1 == d2;
 223:         else
 224:           return d1.equals(d2);
 225:       }
 226:     else return false;
 227:   }
 228: 
 229:   /**
 230:    * Get the hash code (from IOR reference).
 231:    */
 232:   public int hashCode(Stub self)
 233:   {
 234:     Delegate d = self._get_delegate();
 235:     return d==null?0:d.hashCode();
 236:   }
 237: 
 238:   /**
 239:    * Returns the IOR reference of the connected ORB.
 240:    *
 241:    * @see ORB#object_to_string(org.omg.CORBA.Object);
 242:    */
 243:   public String toString(Stub self)
 244:   {
 245:     try
 246:       {
 247:         return self._orb().object_to_string(self);
 248:       }
 249:     catch (Exception ex)
 250:       {
 251:         return null;
 252:       }
 253:   }
 254: 
 255:   /**
 256:    * This should never be called. The ORB must be supplied.
 257:    *
 258:    * @see #connect
 259:    */
 260:   public void readObject(Stub self, ObjectInputStream input)
 261:     throws IOException, ClassNotFoundException
 262:   {
 263:     readObject(self, input, null);
 264:   }
 265: 
 266:   /**
 267:    * Read as CORBA object when the ORB is known. The ORB must be set under the
 268:    * previous call of Stub.connect. The Stub is automatically registered with
 269:    * this ORB.
 270:    */
 271:   public void readObject(Stub self, ObjectInputStream input, ORB orb)
 272:     throws IOException, ClassNotFoundException
 273:   {
 274:     byte[] b = (byte[]) input.readObject();
 275:     BufferredCdrInput in = new BufferredCdrInput(b);
 276: 
 277:     if (orb != null)
 278:       in.setOrb(orb);
 279: 
 280:     ObjectImpl r = (ObjectImpl) in.read_Object();
 281: 
 282:     self._set_delegate(r._get_delegate());
 283:   }
 284: 
 285:   /**
 286:    * Write as CORBA object. The ORB is taken from the
 287:    * org.omg.CORBA.portable.Delegate. The Stub is automatically registered with
 288:    * this ORB (if not already done).
 289:    */
 290:   public void writeObject(Stub self, ObjectOutputStream output)
 291:     throws IOException
 292:   {
 293:     writeObject(self, output, null);
 294:   }
 295: 
 296:   /**
 297:    * Write as CORBA object. The ORB must be either set under the previous call
 298:    * of Stub.connect or it is taken from the org.omg.CORBA.portable.Delegate.
 299:    * The Stub is automatically registered with this ORB (if not already done).
 300:    */
 301:   public void writeObject(Stub self, ObjectOutputStream output, ORB orb)
 302:     throws IOException
 303:   {
 304:     BufferedCdrOutput out = new BufferedCdrOutput();
 305:     out.setOrb(orb == null ? self._orb() : orb);
 306:     out.write_Object(self);
 307: 
 308:     output.writeObject(out.buffer.toByteArray());
 309:   }
 310: }