Source for gnu.CORBA.Poa.gnuServantObject

   1: /* gnuServantObject.java --
   2:    Copyright (C) 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.CORBA.Poa;
  40: 
  41: import gnu.CORBA.GIOP.ReplyHeader;
  42: import gnu.CORBA.IorDelegate;
  43: import gnu.CORBA.IorObject;
  44: import gnu.CORBA.Interceptor.gnuServerRequestInfo;
  45: import gnu.CORBA.typecodes.RecordTypeCode;
  46: import gnu.CORBA.IOR;
  47: import gnu.CORBA.IorProvider;
  48: import gnu.CORBA.Minor;
  49: import gnu.CORBA.ObjectCreator;
  50: import gnu.CORBA.Unexpected;
  51: import gnu.CORBA.ResponseHandlerImpl;
  52: import gnu.CORBA.StreamHolder;
  53: 
  54: import org.omg.CORBA.Any;
  55: import org.omg.CORBA.BAD_OPERATION;
  56: import org.omg.CORBA.BAD_PARAM;
  57: import org.omg.CORBA.CompletionStatus;
  58: import org.omg.CORBA.OBJECT_NOT_EXIST;
  59: import org.omg.CORBA.OBJ_ADAPTER;
  60: import org.omg.CORBA.ORB;
  61: import org.omg.CORBA.SystemException;
  62: import org.omg.CORBA.TCKind;
  63: import org.omg.CORBA.TRANSIENT;
  64: import org.omg.CORBA.UserException;
  65: import org.omg.CORBA.portable.InputStream;
  66: import org.omg.CORBA.portable.InvokeHandler;
  67: import org.omg.CORBA.portable.ObjectImpl;
  68: import org.omg.CORBA.portable.OutputStream;
  69: import org.omg.CORBA.portable.ResponseHandler;
  70: import org.omg.PortableInterceptor.ForwardRequest;
  71: import org.omg.PortableInterceptor.ServerRequestInterceptorOperations;
  72: import org.omg.PortableServer.CurrentOperations;
  73: import org.omg.PortableServer.DynamicImplementation;
  74: import org.omg.PortableServer.ImplicitActivationPolicyValue;
  75: import org.omg.PortableServer.POA;
  76: import org.omg.PortableServer.POAManager;
  77: import org.omg.PortableServer.POAManagerPackage.State;
  78: import org.omg.PortableServer.Servant;
  79: import org.omg.PortableServer.ServantLocatorPackage.CookieHolder;
  80: import org.omg.PortableServer.ServantRetentionPolicyValue;
  81: import org.omg.PortableServer.portable.Delegate;
  82: 
  83: import java.io.IOException;
  84: 
  85: import java.util.Arrays;
  86: 
  87: /**
  88:  * Represents a CORBA object, being locally served by the associated servant.
  89:  * The calls to the object are forwarded to the calls to the servant.
  90:  *
  91:  * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org)
  92:  */
  93: public class gnuServantObject extends ObjectImpl
  94:   implements org.omg.CORBA.Object,
  95:     InvokeHandler,
  96:     CurrentOperations,
  97:     IorProvider
  98: {
  99:   /**
 100:    * The associated servant that must also implement the {@link InvokeHandler}
 101:        * interface. This value can be temporary null if the object was created using
 102:    * POA.create_reference or POA.create_reference_with_id, private to force
 103:    * always to use {@link setServant}.
 104:    */
 105:   private Servant servant;
 106: 
 107:   /**
 108:    * The Id of this object.
 109:    */
 110:   public final byte[] Id;
 111: 
 112:   /**
 113:    * The poa that takes care about this object.
 114:    */
 115:   public final gnuPOA poa;
 116: 
 117:   /**
 118:    * The POA manager, used to control the work of this object.
 119:    */
 120:   public final POAManager manager;
 121: 
 122:   /**
 123:    * The orb.
 124:    */
 125:   public final ORB_1_4 orb;
 126: 
 127:   /**
 128:    * The object repository ids, if they were specified separately. Normally, the
 129:    * ids are requested from the servant.
 130:    */
 131:   public final String[] repository_ids;
 132:   
 133:   /**
 134:    * True indicates that the NO_RETAIN policy applies for the servant.
 135:    * The servant must be discarded after the each call.
 136:    */
 137:   boolean noRetain;
 138: 
 139:   /**
 140:    * Create an object with no connected servant. The servant must be set later.
 141:    *
 142:    * @param a_repository_ids an array of repository ids, can be null (then ids
 143:    * will be requested from the servant).
 144:    * @param an_id the object id.
 145:    * @param a_poa the POA.
 146:    */
 147:   public gnuServantObject(String[] a_repository_ids, byte[] an_id,
 148:     gnuPOA a_poa, ORB_1_4 an_orb
 149:   )
 150:   {
 151:     repository_ids = a_repository_ids;
 152:     Id = an_id;
 153:     manager = a_poa.the_POAManager();
 154:     poa = a_poa;
 155:     orb = an_orb;
 156:     
 157:     noRetain = poa.applies(ServantRetentionPolicyValue.NON_RETAIN);    
 158:   }
 159:   
 160:   /**
 161:    * Get the IOR as it would be for this object.
 162:    */
 163:   public IOR getIor()
 164:   {
 165:     return orb.getLocalIor(this);    
 166:   }
 167: 
 168:   /**
 169:    * Create a servant object, associated with the passed servant.
 170:    *
 171:    * @param a_servant a servant, serving this object.
 172:    * @param an_id an Object Id for this object.
 173:    *
 174:    * @throws BAD_PARAM if the passed servant is not an {@link InvokeHandler}.
 175:    */
 176:   public gnuServantObject(Servant a_servant, byte[] an_id, ORB_1_4 an_orb,
 177:     gnuPOA a_poa
 178:   )
 179:   {
 180:     Id = an_id;
 181:     setServant(a_servant);
 182:     poa = a_poa;
 183:     if (poa != null)
 184:       {
 185:         manager = poa.the_POAManager();
 186:       }
 187:     else
 188:       {
 189:         manager = null;
 190:       }
 191:     repository_ids = null;
 192:     orb = an_orb;
 193:     
 194:     noRetain = poa != null && poa.applies(ServantRetentionPolicyValue.NON_RETAIN);
 195:   }
 196: 
 197:   /**
 198:    * Set a servant, if it has not been previously set.
 199:    *
 200:    * @param a_servant a servant to set, can be null to indicate the necessity
 201:    * for the subsequent activation.
 202:    *
 203:    * @throws BAD_PARAM if the passed servant is not an {@link InvokeHandler} or
 204:    * {@link DynamicImplementation} and also not null.
 205:    */
 206:   public void setServant(Servant a_servant)
 207:   {
 208:     if (a_servant != null &&
 209:       !(a_servant instanceof InvokeHandler) &&
 210:       !(a_servant instanceof DynamicImplementation)
 211:     )
 212:       {
 213:         throw new BAD_PARAM("Must be either InvokeHandler or " +
 214:           "DynamicImplementation, but is " + a_servant
 215:         );
 216:       }
 217:     servant = a_servant;
 218:   }
 219: 
 220:   /**
 221:    * Returns the associated servant.
 222:    */
 223:   public Servant getServant()
 224:   {
 225:     return servant;
 226:   }
 227: 
 228:   /**
 229:    * Return the associated invocation handler.
 230:    */
 231:   public InvokeHandler getHandler(String operation, CookieHolder cookie,
 232:     boolean forwarding_allowed
 233:   ) throws gnuForwardRequest
 234:   {
 235:     if (servant != null && !noRetain)
 236:       {
 237:         return servantToHandler(servant);
 238:       }
 239:     else
 240:       {
 241:         // Use servant locator to locate the servant.
 242:         if (poa.servant_locator != null)
 243:           {
 244:             try
 245:               {
 246:                 servant =
 247:                   poa.servant_locator.preinvoke(Id, poa, operation, cookie);
 248:                 return servantToHandler(servant);
 249:               }
 250:             catch (org.omg.PortableServer.ForwardRequest forw_ex)
 251:               {
 252:                 if (forwarding_allowed)
 253:                   {
 254:                     throw new gnuForwardRequest(forw_ex.forward_reference);
 255:                   }
 256:                 else
 257:                   {
 258:                     servant =
 259:                       ForwardedServant.create(forw_ex.forward_reference);
 260:                     return servantToHandler(servant);
 261:                   }
 262:               }
 263:           }
 264:         else
 265:         // Use servant activator to locate the servant.
 266:         if (poa.applies(ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION) &&
 267:           poa.applies(ServantRetentionPolicyValue.RETAIN)
 268:         )
 269:           {
 270:             try
 271:               {
 272:                 poa.activate_object_with_id(Id, servant, forwarding_allowed);
 273:                 servant = poa.id_to_servant(Id);
 274:                 return servantToHandler(servant);
 275:               }
 276:             catch (gnuForwardRequest forwarded)
 277:               {
 278:                 throw forwarded;
 279:               }
 280:             catch (Exception ex)
 281:               {
 282:                 BAD_OPERATION bad =
 283:                   new BAD_OPERATION("Unable to activate", Minor.Activation,
 284:                     CompletionStatus.COMPLETED_NO
 285:                   );
 286:                 bad.initCause(ex);
 287:                 throw bad;
 288:               }
 289:           }
 290:         else if (poa.default_servant != null)
 291:           {
 292:             servant = poa.default_servant;
 293:             return servantToHandler(servant);
 294:           }
 295: 
 296:         // No servant and no servant manager - throw exception.
 297:         else
 298:           {
 299:             throw new BAD_OPERATION("Unable to activate", Minor.Activation,
 300:               CompletionStatus.COMPLETED_NO
 301:             );
 302:           }
 303:       }
 304:   }
 305: 
 306:   /**
 307:    * Convert the servant to invocation handler.
 308:    */
 309:   public InvokeHandler servantToHandler(Servant a_servant)
 310:   {
 311:     if (a_servant instanceof InvokeHandler)
 312:       {
 313:         return (InvokeHandler) a_servant;
 314:       }
 315:     else if (a_servant instanceof DynamicImplementation)
 316:       {
 317:         return new DynamicImpHandler((DynamicImplementation) a_servant);
 318:       }
 319:     else
 320:       {
 321:         throw new BAD_OPERATION(a_servant +
 322:           " must be either InvokeHandler or " + "POA DynamicImplementation"
 323:         );
 324:       }
 325:   }
 326: 
 327:   /**
 328:    * Create a servant object, associated with the passed servant. Requests the
 329:    * object id from the servant. Depending on the policies of the servants POA,
 330:    * the calls are eithe not synchronized or synchronized on POA or ORB.
 331:    *
 332:    * @param a_servant a servant, serving this object.
 333:    * @param an_id an Object Id for this object.
 334:    */
 335:   public gnuServantObject(Servant a_servant, gnuPOA a_poa)
 336:   {
 337:     this(a_servant, a_servant._object_id(), (ORB_1_4) a_servant._orb(), a_poa);
 338:   }
 339: 
 340:   /**
 341:    * Delegates call to servant, passing the poa and Id.
 342:    */
 343:   public String[] _ids()
 344:   {
 345:     if (repository_ids == null)
 346:       {
 347:         return getServant()._all_interfaces(poa, Id);
 348:       }
 349:     else
 350:       {
 351:         return repository_ids;
 352:       }
 353:   }
 354: 
 355:   /**
 356:    * Gets a string representation.
 357:    */
 358:   public String toString()
 359:   {
 360:     StringBuffer b = new StringBuffer("Servant object (");
 361:     for (int i = 0; i < Id.length; i++)
 362:       {
 363:         b.append(Integer.toHexString(Id [ i ] & 0xFF));
 364:         b.append(' ');
 365:       }
 366:     b.append(')');
 367:     return b.toString();
 368:   }
 369: 
 370:   /**
 371:    * Always returns true.
 372:    */
 373:   public boolean _is_local()
 374:   {
 375:     return true;
 376:   }
 377: 
 378:   /**
 379:    * Check if this object could be named by the given repository id.
 380:    *
 381:    * @param idl_id the repository id to check.
 382:    *
 383:    * @return true if it is one of the possible repository ids of this object.
 384:    */
 385:   public boolean _is_a(String idl_id)
 386:   {
 387:     String[] maybe = _ids();
 388:     for (int i = 0; i < maybe.length; i++)
 389:       {
 390:         if (maybe [ i ].equals(idl_id))
 391:           {
 392:             return true;
 393:           }
 394:       }
 395:     return false;
 396:   }
 397: 
 398:   /**
 399:    * Get an ORB, associated with the servant of this object.
 400:    *
 401:    * @return
 402:    */
 403:   public ORB _orb()
 404:   {
 405:     return getServant()._orb();
 406:   }
 407: 
 408:   /**
 409:    * Handle the invocation (delegates to servant).
 410:    *
 411:    * @throws TRANSIENT minor 0x535503e9 if the POA is in discarding mode.
 412:    * @throws OBJ_ADAPTER minor 0x535503ea if the POA is inactivated.
 413:    * @throws OBJECT_NOT_EXISTS minor 0x535503ec if this object is inactivated.
 414:    *
 415:    * @specnote see {@link POAManagerOperations} for specnotes about the minor
 416:    * codes.
 417:    */
 418:   public OutputStream _invoke(String method, InputStream input,
 419:     ResponseHandler r_handler
 420:   ) throws SystemException
 421:   {
 422:     boolean intercept = false;
 423:     ServerRequestInterceptorOperations interceptor = null;
 424:     gnuServerRequestInfo info = null;
 425:     ResponseHandlerImpl i_handler = null;
 426: 
 427:     try
 428:       {
 429:         if (orb.iServer != null &&
 430:           r_handler instanceof ResponseHandlerImpl
 431:         )
 432:           {
 433:             interceptor = orb.iServer;
 434: 
 435:             i_handler = (ResponseHandlerImpl) r_handler;
 436: 
 437:             info =
 438:               new gnuServerRequestInfo(this, i_handler.request_header,
 439:                 i_handler.reply_header
 440:               );
 441:             intercept = true;
 442: 
 443:             interceptor.receive_request_service_contexts(info);
 444:           }
 445: 
 446:         try
 447:           {
 448:             CookieHolder cookie = null;
 449:             AOM.Obj self = poa.aom.get(Id);
 450: 
 451:             if (poa.servant_locator != null)
 452:               {
 453:                 // If the servant locator is in use, it is always responsible
 454:                 // for providing the servant.
 455:                 self.servant = servant = null;
 456:                 cookie = new CookieHolder();
 457:               }
 458:             else if (self != null && self.isDeactiveted())
 459:               {
 460:                 if (poa.applies(
 461:                     ImplicitActivationPolicyValue.IMPLICIT_ACTIVATION
 462:                   ) &&
 463:                   poa.servant_activator != null
 464:                 )
 465:                   {
 466:                     // Reset the servant, forcing the subsequent activation.
 467:                     servant = null;
 468:                   }
 469:                 else
 470:                   {
 471:                     throw new OBJECT_NOT_EXIST("Object deactivated",
 472:                       0x535503ec, CompletionStatus.COMPLETED_NO
 473:                     );
 474:                   }
 475:               }
 476: 
 477:             InvokeHandler handler = getHandler(method, cookie, true);
 478: 
 479:             Delegate d = null;
 480: 
 481:             try
 482:               {
 483:                 d = servant._get_delegate();
 484:                 orb.currents.put(Thread.currentThread(), this);
 485:               }
 486:             catch (Exception ex)
 487:               {
 488:                 // In some cases exception is thrown if the delegate is not set.
 489:               }
 490:             if (d instanceof ServantDelegateImpl)
 491:               {
 492:                 // If the delegate is already set, check maybe we can
 493:                 // reuse the existing instance.
 494:                 if (((ServantDelegateImpl) d).object != this)
 495:                   {
 496:                     servant._set_delegate(new ServantDelegateImpl(servant, poa, Id));
 497:                   }
 498:               }
 499:             else
 500:               {
 501:                 servant._set_delegate(new ServantDelegateImpl(servant, poa, Id));
 502:               }
 503: 
 504:             try
 505:               {
 506:                 switch (manager.get_state().value())
 507:                   {
 508:                     case State._ACTIVE :
 509: 
 510:                       OutputStream rt;
 511:                       try
 512:                         {
 513:                           if (intercept)
 514:                             {
 515:                               interceptor.receive_request(info);
 516:                             }
 517: 
 518:                           rt = handler._invoke(method, input, r_handler);
 519: 
 520:                           if (intercept)
 521:                             {
 522:                               // Handler is casted into i_handler.
 523:                               if (i_handler.isExceptionReply())
 524:                                 {
 525:                                   info.m_reply_header.reply_status =
 526:                                     ReplyHeader.USER_EXCEPTION;
 527: 
 528:                                   // Make Any, holding the user exception.
 529:                                   Any a = orb.create_any();
 530:                                   OutputStream buf = i_handler.getBuffer();
 531:                                   InputStream in = buf.create_input_stream();
 532:                                   String uex_idl = "unknown";
 533:                                   try
 534:                                     {
 535:                                       in.mark(Integer.MAX_VALUE);
 536:                                       uex_idl = in.read_string();
 537:                                       in.reset();
 538:                                     }
 539:                                   catch (IOException e)
 540:                                     {
 541:                                       throw new Unexpected(e);
 542:                                     }
 543: 
 544:                                   try
 545:                                     {
 546:                                       UserException exception =
 547:                                         ObjectCreator.readUserException(uex_idl,
 548:                                           in
 549:                                         );
 550: 
 551:                                       ObjectCreator.insertWithHelper(a,
 552:                                         exception
 553:                                       );
 554:                                     }
 555:                                   catch (Exception e)
 556:                                     {
 557:                                       // Failed due any reason, insert without
 558:                                       // helper.
 559:                                       a.insert_Streamable(new StreamHolder(
 560:                                           buf.create_input_stream()
 561:                                         )
 562:                                       );
 563: 
 564:                                       RecordTypeCode r =
 565:                                         new RecordTypeCode(TCKind.tk_except);
 566:                                       r.setId(uex_idl);
 567:                                       r.setName(ObjectCreator.getDefaultName(
 568:                                           uex_idl
 569:                                         )
 570:                                       );
 571:                                     }
 572: 
 573:                                   info.m_usr_exception = a;
 574:                                   interceptor.send_exception(info);
 575:                                 }
 576:                               else
 577:                                 {
 578:                                   info.m_reply_header.reply_status =
 579:                                     ReplyHeader.NO_EXCEPTION;
 580:                                   interceptor.send_reply(info);
 581:                                 }
 582:                             }
 583:                         }
 584:                       catch (SystemException sys_ex)
 585:                         {
 586:                           if (intercept)
 587:                             {
 588:                               info.m_reply_header.reply_status =
 589:                                 ReplyHeader.SYSTEM_EXCEPTION;
 590:                               info.m_sys_exception = sys_ex;
 591:                               interceptor.send_exception(info);
 592:                             }
 593:                           throw sys_ex;
 594:                         }
 595: 
 596:                       return rt;
 597: 
 598:                     case State._HOLDING :
 599: 
 600:                       // The holding mode is implemented
 601:                       // relying on the holding capabilites of the network
 602:                       // support (if any).
 603:                       // TODO FIXME in more recent CORBA applications, the
 604:                       // client
 605:                       // ORB can free the connection and wait for a server side
 606:                       // notification about the completed request. Implement
 607:                       // this
 608:                       // as soon as JDK specification would allow bidirectional
 609:                       // policy.
 610:                       int sleep = 5;
 611:                       int max = 500;
 612: 
 613:                       // Wait till the state will be switched into some other
 614:                       // mode.
 615:                       while (manager.get_state().value() == State._HOLDING)
 616:                         {
 617:                           try
 618:                             {
 619:                               Thread.sleep(sleep);
 620:                               if (sleep < max)
 621:                                 {
 622:                                   sleep = max;
 623:                                 }
 624:                             }
 625:                           catch (InterruptedException ex)
 626:                             {
 627:                             }
 628:                         }
 629: 
 630:                       // Handle another mode.
 631:                       return _invoke(method, input, r_handler);
 632: 
 633:                     case State._DISCARDING :
 634:                       throw new TRANSIENT("Discarding mode", 0x535503e9,
 635:                         CompletionStatus.COMPLETED_NO
 636:                       );
 637: 
 638:                     case State._INACTIVE :
 639:                       throw new OBJ_ADAPTER("POA deactivated", 0x535503ea,
 640:                         CompletionStatus.COMPLETED_NO
 641:                       );
 642: 
 643:                     default :
 644:                       throw new InternalError(); // No more states.
 645:                   }
 646:               }
 647:             finally
 648:               {
 649:                 if (poa.servant_locator != null)
 650:                   {
 651:                     poa.servant_locator.postinvoke(Id, poa, method,
 652:                       cookie.value, servant
 653:                     );
 654:                   }
 655:               }
 656:           }
 657:         finally
 658:           {
 659:             orb.currents.remove(Thread.currentThread());
 660:             if (noRetain)
 661:               servant = null;
 662:           }
 663:       }
 664:     catch (ForwardRequest fex)
 665:       {
 666:         // May be thrown by interceptor.
 667:         if (intercept)
 668:           {
 669:             Forwarding:
 670:             while (true)
 671:               {
 672:                 info.m_reply_header.reply_status =
 673:                   ReplyHeader.LOCATION_FORWARD;
 674:                 info.m_forward_reference = fex.forward;
 675:                 try
 676:                   {
 677:                     interceptor.send_other(info);
 678:                     break Forwarding;
 679:                   }
 680:                 catch (ForwardRequest fex2)
 681:                   {
 682:                     info.m_forward_reference = fex2.forward;
 683:                     fex.forward = info.m_forward_reference;
 684:                   }
 685:               }
 686:           }
 687:         throw new gnuForwardRequest(fex.forward);
 688:       }
 689:     catch (gnuForwardRequest fex)
 690:       {
 691:         // May be thrown during activation.
 692:         if (intercept)
 693:           {
 694:             Forwarding:
 695:             while (true)
 696:               {
 697:                 info.m_reply_header.reply_status =
 698:                   ReplyHeader.LOCATION_FORWARD;
 699:                 info.m_forward_reference = fex.forward_reference;
 700:                 try
 701:                   {
 702:                     interceptor.send_other(info);
 703:                     break Forwarding;
 704:                   }
 705:                 catch (ForwardRequest fex2)
 706:                   {
 707:                     info.m_forward_reference = fex2.forward;
 708:                     fex.forward_reference = (ObjectImpl) fex2.forward;
 709:                   }
 710:               }
 711:           }
 712:         throw fex;
 713:       }
 714:   }
 715: 
 716:   /**
 717:    * Compare with another object for equality, comparing the object keys.
 718:    */
 719:   public boolean equals(java.lang.Object other)
 720:   {
 721:     if (other instanceof gnuServantObject)
 722:       {
 723:         gnuServantObject o = (gnuServantObject) other;
 724: 
 725:         return Arrays.equals(o.Id, Id);
 726:       }
 727:     else
 728:       {
 729:         return false;
 730:       }
 731:   }
 732: 
 733:   /**
 734:    * Get the hash code, based on the object key.
 735:    */
 736:   public int hashCode()
 737:   {
 738:     long s = 0;
 739:     int v = 1;
 740:     for (int i = 0; i < Id.length; i++)
 741:       {
 742:         s += Id [ i ] * v;
 743:         if (s > Integer.MAX_VALUE)
 744:           {
 745:             s = s % Integer.MAX_VALUE;
 746:             v = 1;
 747:           }
 748:         v = v * 8;
 749:       }
 750:     return (int) (s % Integer.MAX_VALUE);
 751:   }
 752: 
 753:   /**
 754:    * Get the object id.
 755:    */
 756:   public byte[] get_object_id()
 757:   {
 758:     return Id;
 759:   }
 760: 
 761:   /**
 762:    * Get POA.
 763:    */
 764:   public POA get_POA()
 765:   {
 766:     return poa;
 767:   }
 768: 
 769:   /**
 770:    * Returns without action.
 771:    */
 772:   public void _release()
 773:   {
 774:   }
 775: 
 776:   /**
 777:    * Returns without action.
 778:    */
 779:   public void _releaseReply(InputStream stream)
 780:   {
 781:   }
 782: 
 783:   /**
 784:    * Checks if this object is equivalent to another instance. These objects are
 785:    * assumed equal if they are connected to the same orb and poa under the same
 786:    * Id, regardless of they delegates.
 787:    *
 788:    * @param another instance to check.
 789:    * @return
 790:    */
 791:   public boolean _is_equivalent(org.omg.CORBA.Object other)
 792:   {
 793:     if (other instanceof gnuServantObject)
 794:       {
 795:         gnuServantObject g = (gnuServantObject) other;
 796:         return orb == g.orb && poa == g.poa && Arrays.equals(Id, g.Id);
 797:       }
 798:     else if (other instanceof IorObject)
 799:       {
 800:         IorObject ir = ((IorObject) other);
 801:         try
 802:           {
 803:             IorDelegate ird = (IorDelegate) ir._get_delegate();
 804:             byte[] ior_id = poa.idFormIor(ird.getIor().key);
 805:             if (ior_id != null && Arrays.equals(ior_id, Id))
 806:               {
 807:                 return true;
 808:               }
 809:             else
 810:               {
 811:                 return false;
 812:               }
 813:           }
 814:         catch (Exception ex)
 815:           {
 816:             // Non - typical delegate or very specific subclass of
 817:             // IOR_constructed_object.
 818:             return super._is_equivalent(other);
 819:           }
 820:       }
 821:     return super._is_equivalent(other);
 822:   }