CorbaClientDelegateImpl.java revision 608:7e06bf1dcb09
1/* 2 * Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.sun.corba.se.impl.protocol; 27 28import java.util.Iterator; 29import java.util.HashMap; 30 31import javax.rmi.CORBA.Tie; 32 33import org.omg.CORBA.CompletionStatus; 34import org.omg.CORBA.Context; 35import org.omg.CORBA.ContextList; 36import org.omg.CORBA.ExceptionList; 37import org.omg.CORBA.NamedValue; 38import org.omg.CORBA.NVList; 39import org.omg.CORBA.Request; 40import org.omg.CORBA.TypeCode; 41 42import org.omg.CORBA.portable.ApplicationException; 43import org.omg.CORBA.portable.Delegate; 44import org.omg.CORBA.portable.InputStream; 45import org.omg.CORBA.portable.OutputStream; 46import org.omg.CORBA.portable.RemarshalException; 47import org.omg.CORBA.portable.ServantObject; 48 49import com.sun.corba.se.pept.broker.Broker; 50import com.sun.corba.se.pept.encoding.InputObject; 51import com.sun.corba.se.pept.encoding.OutputObject; 52import com.sun.corba.se.pept.protocol.ClientInvocationInfo; 53import com.sun.corba.se.pept.protocol.ClientRequestDispatcher; 54import com.sun.corba.se.pept.transport.ContactInfo; 55import com.sun.corba.se.pept.transport.ContactInfoList; 56import com.sun.corba.se.pept.transport.ContactInfoListIterator; 57 58import com.sun.corba.se.spi.presentation.rmi.StubAdapter; 59import com.sun.corba.se.spi.ior.IOR; 60import com.sun.corba.se.spi.logging.CORBALogDomains; 61import com.sun.corba.se.spi.orb.ORB; 62import com.sun.corba.se.spi.protocol.CorbaClientDelegate ; 63import com.sun.corba.se.spi.transport.CorbaContactInfo; 64import com.sun.corba.se.spi.transport.CorbaContactInfoList; 65import com.sun.corba.se.spi.transport.CorbaContactInfoListIterator; 66 67import com.sun.corba.se.impl.corba.RequestImpl; 68import com.sun.corba.se.impl.protocol.CorbaInvocationInfo; 69import com.sun.corba.se.impl.transport.CorbaContactInfoListImpl; 70import com.sun.corba.se.impl.util.JDKBridge; 71import com.sun.corba.se.impl.logging.ORBUtilSystemException; 72 73// implements com.sun.corba.se.impl.core.ClientRequestDispatcher 74// so RMI-IIOP Util.isLocal can call ClientRequestDispatcher.useLocalInvocation. 75 76/** 77 * @author Harold Carr 78 */ 79public class CorbaClientDelegateImpl extends CorbaClientDelegate 80{ 81 private ORB orb; 82 private ORBUtilSystemException wrapper ; 83 84 private CorbaContactInfoList contactInfoList; 85 86 public CorbaClientDelegateImpl(ORB orb, 87 CorbaContactInfoList contactInfoList) 88 { 89 this.orb = orb; 90 this.wrapper = ORBUtilSystemException.get( orb, 91 CORBALogDomains.RPC_PROTOCOL ) ; 92 this.contactInfoList = contactInfoList; 93 } 94 95 // 96 // framework.subcontract.Delegate 97 // 98 99 public Broker getBroker() 100 { 101 return orb; 102 } 103 104 public ContactInfoList getContactInfoList() 105 { 106 return contactInfoList; 107 } 108 109 // 110 // CORBA_2_3.portable.Delegate 111 // 112 113 public OutputStream request(org.omg.CORBA.Object self, 114 String operation, 115 boolean responseExpected) 116 { 117 ClientInvocationInfo invocationInfo = 118 orb.createOrIncrementInvocationInfo(); 119 Iterator contactInfoListIterator = 120 invocationInfo.getContactInfoListIterator(); 121 if (contactInfoListIterator == null) { 122 contactInfoListIterator = contactInfoList.iterator(); 123 invocationInfo.setContactInfoListIterator(contactInfoListIterator); 124 } 125 if (! contactInfoListIterator.hasNext()) { 126 throw ((CorbaContactInfoListIterator)contactInfoListIterator) 127 .getFailureException(); 128 } 129 CorbaContactInfo contactInfo = (CorbaContactInfo) contactInfoListIterator.next(); 130 ClientRequestDispatcher subcontract = contactInfo.getClientRequestDispatcher(); 131 // Remember chosen subcontract for invoke and releaseReply. 132 // NOTE: This is necessary since a stream is not available in 133 // releaseReply if there is a client marshaling error or an 134 // error in _invoke. 135 invocationInfo.setClientRequestDispatcher(subcontract); 136 return (OutputStream) 137 subcontract.beginRequest(self, operation, 138 !responseExpected, contactInfo); 139 } 140 141 public InputStream invoke(org.omg.CORBA.Object self, OutputStream output) 142 throws 143 ApplicationException, 144 RemarshalException 145 { 146 ClientRequestDispatcher subcontract = getClientRequestDispatcher(); 147 return (InputStream) 148 subcontract.marshalingComplete((Object)self, (OutputObject)output); 149 } 150 151 public void releaseReply(org.omg.CORBA.Object self, InputStream input) 152 { 153 // NOTE: InputStream may be null (e.g., exception request from PI). 154 ClientRequestDispatcher subcontract = getClientRequestDispatcher(); 155 subcontract.endRequest(orb, self, (InputObject)input); 156 orb.releaseOrDecrementInvocationInfo(); 157 } 158 159 private ClientRequestDispatcher getClientRequestDispatcher() 160 { 161 return (ClientRequestDispatcher) 162 ((CorbaInvocationInfo)orb.getInvocationInfo()) 163 .getClientRequestDispatcher(); 164 } 165 166 public org.omg.CORBA.Object get_interface_def(org.omg.CORBA.Object obj) 167 { 168 InputStream is = null; 169 // instantiate the stub 170 org.omg.CORBA.Object stub = null ; 171 172 try { 173 OutputStream os = request(null, "_interface", true); 174 is = (InputStream) invoke((org.omg.CORBA.Object)null, os); 175 176 org.omg.CORBA.Object objimpl = 177 (org.omg.CORBA.Object) is.read_Object(); 178 179 // check if returned object is of correct type 180 if ( !objimpl._is_a("IDL:omg.org/CORBA/InterfaceDef:1.0") ) 181 throw wrapper.wrongInterfaceDef(CompletionStatus.COMPLETED_MAYBE); 182 183 try { 184 stub = (org.omg.CORBA.Object) 185 JDKBridge.loadClass("org.omg.CORBA._InterfaceDefStub"). 186 newInstance(); 187 } catch (Exception ex) { 188 throw wrapper.noInterfaceDefStub( ex ) ; 189 } 190 191 org.omg.CORBA.portable.Delegate del = 192 StubAdapter.getDelegate( objimpl ) ; 193 StubAdapter.setDelegate( stub, del ) ; 194 } catch (ApplicationException e) { 195 // This cannot happen. 196 throw wrapper.applicationExceptionInSpecialMethod( e ) ; 197 } catch (RemarshalException e) { 198 return get_interface_def(obj); 199 } finally { 200 releaseReply((org.omg.CORBA.Object)null, (InputStream)is); 201 } 202 203 return stub; 204 } 205 206 public boolean is_a(org.omg.CORBA.Object obj, String dest) 207 { 208 // dest is the typeId of the interface to compare against. 209 // repositoryIds is the list of typeIds that the stub knows about. 210 211 // First we look for an answer using local information. 212 213 String [] repositoryIds = StubAdapter.getTypeIds( obj ) ; 214 String myid = contactInfoList.getTargetIOR().getTypeId(); 215 if ( dest.equals(myid) ) { 216 return true; 217 } 218 for ( int i=0; i<repositoryIds.length; i++ ) { 219 if ( dest.equals(repositoryIds[i]) ) { 220 return true; 221 } 222 } 223 224 // But repositoryIds may not be complete, so it may be necessary to 225 // go to server. 226 227 InputStream is = null; 228 try { 229 OutputStream os = request(null, "_is_a", true); 230 os.write_string(dest); 231 is = (InputStream) invoke((org.omg.CORBA.Object) null, os); 232 233 return is.read_boolean(); 234 235 } catch (ApplicationException e) { 236 // This cannot happen. 237 throw wrapper.applicationExceptionInSpecialMethod( e ) ; 238 } catch (RemarshalException e) { 239 return is_a(obj, dest); 240 } finally { 241 releaseReply((org.omg.CORBA.Object)null, (InputStream)is); 242 } 243 } 244 245 public boolean non_existent(org.omg.CORBA.Object obj) 246 { 247 InputStream is = null; 248 try { 249 OutputStream os = request(null, "_non_existent", true); 250 is = (InputStream) invoke((org.omg.CORBA.Object)null, os); 251 252 return is.read_boolean(); 253 254 } catch (ApplicationException e) { 255 // This cannot happen. 256 throw wrapper.applicationExceptionInSpecialMethod( e ) ; 257 } catch (RemarshalException e) { 258 return non_existent(obj); 259 } finally { 260 releaseReply((org.omg.CORBA.Object)null, (InputStream)is); 261 } 262 } 263 264 public org.omg.CORBA.Object duplicate(org.omg.CORBA.Object obj) 265 { 266 return obj; 267 } 268 269 public void release(org.omg.CORBA.Object obj) 270 { 271 // DO NOT clear out internal variables to release memory 272 // This delegate may be pointed-to by other objrefs. 273 } 274 275 // obj._get_delegate() == this due to the argument passing conventions in 276 // portable.ObjectImpl, so we just ignore obj here. 277 public boolean is_equivalent(org.omg.CORBA.Object obj, 278 org.omg.CORBA.Object ref) 279 { 280 if ( ref == null ) 281 return false; 282 283 // If ref is a local object, it is not a Stub! 284 if (!StubAdapter.isStub(ref)) 285 return false ; 286 287 Delegate del = StubAdapter.getDelegate(ref) ; 288 if (del == null) 289 return false ; 290 291 // Optimize the x.is_equivalent( x ) case 292 if (del == this) 293 return true; 294 295 // If delegate was created by a different ORB, return false 296 if (!(del instanceof CorbaClientDelegateImpl)) 297 return false ; 298 299 CorbaClientDelegateImpl corbaDelegate = (CorbaClientDelegateImpl)del ; 300 CorbaContactInfoList ccil = 301 (CorbaContactInfoList)corbaDelegate.getContactInfoList() ; 302 return this.contactInfoList.getTargetIOR().isEquivalent( 303 ccil.getTargetIOR() ); 304 } 305 306 /** 307 * This method overrides the org.omg.CORBA.portable.Delegate.equals method, 308 * and does the equality check based on IOR equality. 309 */ 310 public boolean equals(org.omg.CORBA.Object self, java.lang.Object other) 311 { 312 if (other == null) 313 return false ; 314 315 if (!StubAdapter.isStub(other)) { 316 return false; 317 } 318 319 Delegate delegate = StubAdapter.getDelegate( other ) ; 320 if (delegate == null) 321 return false ; 322 323 if (delegate instanceof CorbaClientDelegateImpl) { 324 CorbaClientDelegateImpl otherDel = (CorbaClientDelegateImpl) 325 delegate ; 326 IOR otherIor = otherDel.contactInfoList.getTargetIOR(); 327 return this.contactInfoList.getTargetIOR().equals(otherIor); 328 } 329 330 // Come here if other is not implemented by our ORB. 331 return false; 332 } 333 334 public int hashCode(org.omg.CORBA.Object obj) 335 { 336 return this.hashCode() ; 337 } 338 339 public int hash(org.omg.CORBA.Object obj, int maximum) 340 { 341 int h = this.hashCode(); 342 if ( h > maximum ) 343 return 0; 344 return h; 345 } 346 347 public Request request(org.omg.CORBA.Object obj, String operation) 348 { 349 return new RequestImpl(orb, obj, null, operation, null, null, null, 350 null); 351 } 352 353 public Request create_request(org.omg.CORBA.Object obj, 354 Context ctx, 355 String operation, 356 NVList arg_list, 357 NamedValue result) 358 { 359 return new RequestImpl(orb, obj, ctx, operation, arg_list, 360 result, null, null); 361 } 362 363 public Request create_request(org.omg.CORBA.Object obj, 364 Context ctx, 365 String operation, 366 NVList arg_list, 367 NamedValue result, 368 ExceptionList exclist, 369 ContextList ctxlist) 370 { 371 return new RequestImpl(orb, obj, ctx, operation, arg_list, result, 372 exclist, ctxlist); 373 } 374 375 public org.omg.CORBA.ORB orb(org.omg.CORBA.Object obj) 376 { 377 return this.orb; 378 } 379 380 /** 381 * Returns true if this object is implemented by a local servant. 382 * 383 * REVISIT: locatedIOR should be replaced with a method call that 384 * returns the current IOR for this request (e.g. ContactInfoChooser). 385 * 386 * @param self The object reference which delegated to this delegate. 387 * @return true only if the servant incarnating this object is located in 388 * this ORB. 389 */ 390 public boolean is_local(org.omg.CORBA.Object self) 391 { 392 // XXX this need to check isNextCallValid 393 return contactInfoList.getEffectiveTargetIOR().getProfile(). 394 isLocal(); 395 } 396 397 public ServantObject servant_preinvoke(org.omg.CORBA.Object self, 398 String operation, 399 Class expectedType) 400 { 401 return 402 contactInfoList.getLocalClientRequestDispatcher() 403 .servant_preinvoke(self, operation, expectedType); 404 } 405 406 public void servant_postinvoke(org.omg.CORBA.Object self, 407 ServantObject servant) 408 { 409 contactInfoList.getLocalClientRequestDispatcher() 410 .servant_postinvoke(self, servant); 411 } 412 413 // XXX Should this be public? 414 /* Returns the codebase for object reference provided. 415 * @param self the object reference whose codebase needs to be returned. 416 * @return the codebase as a space delimited list of url strings or 417 * null if none. 418 */ 419 public String get_codebase(org.omg.CORBA.Object self) 420 { 421 if (contactInfoList.getTargetIOR() != null) { 422 return contactInfoList.getTargetIOR().getProfile().getCodebase(); 423 } 424 return null; 425 } 426 427 public String toString(org.omg.CORBA.Object self) 428 { 429 return contactInfoList.getTargetIOR().stringify(); 430 } 431 432 //////////////////////////////////////////////////// 433 // 434 // java.lang.Object 435 // 436 437 public int hashCode() 438 { 439 return this.contactInfoList.hashCode(); 440 } 441} 442 443// End of file. 444