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 */ connect(Stub self, ORB orb)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 */ connect(Stub self, ORB orb, POA poa)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 */ getTieFromStub(java.lang.Object self)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 */ equals(Stub self, java.lang.Object obj)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 */ hashCode(Stub self)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 */ toString(Stub self)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 */ readObject(Stub self, ObjectInputStream input)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 */ readObject(Stub self, ObjectInputStream input, ORB orb)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 */ writeObject(Stub self, ObjectOutputStream output)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 */ writeObject(Stub self, ObjectOutputStream output, ORB orb)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 } 311