Frames | No Frames |
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: }