Source for org.omg.CORBA.ORB

   1: /* ORB.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 org.omg.CORBA;
  40: 
  41: import gnu.CORBA.OrbFocused;
  42: import gnu.CORBA.ObjectCreator;
  43: import gnu.CORBA.OrbRestricted;
  44: import gnu.CORBA.gnuContext;
  45: import gnu.CORBA.typecodes.FixedTypeCode;
  46: import gnu.CORBA.typecodes.GeneralTypeCode;
  47: import gnu.CORBA.typecodes.PrimitiveTypeCode;
  48: import gnu.CORBA.typecodes.RecordTypeCode;
  49: import gnu.CORBA.typecodes.RecursiveTypeCode;
  50: 
  51: import org.omg.CORBA.ORBPackage.InconsistentTypeCode;
  52: 
  53: import java.applet.Applet;
  54: 
  55: import java.io.BufferedInputStream;
  56: import java.io.File;
  57: import java.io.FileInputStream;
  58: import java.io.IOException;
  59: 
  60: import java.util.Properties;
  61: 
  62: /**
  63:  * A central class in CORBA implementation, responsible for sending and handling
  64:  * remote invocations. ORB also works as a factory for creating instances of
  65:  * certain CORBA classes.
  66:  * 
  67:  * Despite the core library contains the fully working CORBA implementation, it
  68:  * also provides a simple way to plug-in the alternative CORBA support. This is
  69:  * done by replacing the ORB. The alternative ORB can be specified via
  70:  * properties, passed to ORB.Init(...).
  71:  * 
  72:  * When creating an ORB instance, the class name is searched in the following
  73:  * locations:
  74:  * <p>
  75:  * 1. Applet parameter or application string array, if any.<br>
  76:  * 2. The properties parameter, if any.<br>
  77:  * 3. The System properties.<br>
  78:  * 4. The orb.properties file located in the user.home directory (if any).<br>
  79:  * 5. The orb.properties file located in the java.home/lib directory (if any).
  80:  * </p>
  81:  * 
  82:  * The supported properties are: <table border="1">
  83:  * <tr>
  84:  * <td> org.omg.CORBA.ORBClass</td>
  85:  * <td>The class, implementing the functional ORB, returned by
  86:  * {@link #init(Applet, Properties)} or {@link #init(String[], Properties)}
  87:  * </td>
  88:  * </tr>
  89:  * <tr>
  90:  * <td>org.omg.CORBA.ORBSingletonClass</td>
  91:  * <td>The class, implementing the restricted ORB, returned by {@link #init()}.
  92:  * </td>
  93:  * </tr>
  94:  * <tr>
  95:  * <td>org.omg.CORBA.ORBInitRef</td>
  96:  * <td>Specifies the initial reference, accessible by name with the method
  97:  * {@link #resolve_initial_references(String)}.</td>
  98:  * </tr>
  99:  * <tr>
 100:  * <td>gnu.CORBA.ListenerPort</td>
 101:  * <td>Specifies that this ORB should serve all its objects on a single port
 102:  * (for example, "1234") or on a specified port range (for example,
 103:  * "1100-1108"). The property is used when working with firewals and serves as a
 104:  * replacement for the proprietary properties like com.ibm.CORBA.ListenerPort
 105:  * or com.sun.CORBA.POA.ORBPersistentServerPort. The specified port or range
 106:  * should not overlap with the values, specified for other ORB's.
 107:  * </td>
 108:  * </tr>
 109:  * <tr>
 110:  * <td>gnu.Corba.SocketFactory</td>
 111:  * <td>Sets the user-defined server and client socket factory for the ORB being
 112:  * currently instantiated. Serves as a replacement of the proprietary
 113:  * property com.sun.CORBA.connection.ORBSocketFactoryClass. To have multiple
 114:  * types of sockets, instantiate several ORB's with this property each time
 115:  * set to the different value. 
 116:  * The factory must implement gnu.CORBA.interfaces.SocketFactory.
 117:  * </td>
 118:  * </tr>
 119:  * </table> 
 120:  * <p>The command line accepts the same properties as a keys. When
 121:  * specifying in the command line, the prefix org.omg.CORBA can be omitted, for
 122:  * instance<code> -ORBInitRef NameService=IOR:aabbccdd....</code>
 123:  * </p>
 124:  * 
 125:  * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
 126:  */
 127: public abstract class ORB
 128: {
 129:   /**
 130:   * By default, {@link #init(String[], Properties)} and
 131:   * {@link #iinit(Applet, Properties)} return
 132:   * the built-in fully functional ORB is returned. If the
 133:   * <code>props</code> contains the property org.omg.CORBA.ORBClass,
 134:   * the value of this property is used as a class name to instantiate
 135:   * a user-defined ORB.
 136:   */
 137:   private static final String FUNCTIONAL_ORB = "org.omg.CORBA.ORBClass";
 138: 
 139:   /**
 140:    * The name of the restricted ORB property.
 141:    */
 142:   private static final String RESTRICTED_ORB =
 143:     "org.omg.CORBA.ORBSingletonClass";
 144:   
 145:   private static final String LISTENER_PORT =
 146:     OrbFocused.LISTENER_PORT;
 147:   
 148:   /**
 149:    * The class, implementing the default fully functional ORB.
 150:    */
 151:   private static final String DEFAULT_FUNCTIONAL_ORB =
 152:     gnu.CORBA.Poa.ORB_1_4.class.getName();
 153:   
 154:   private static final String DEFAULT_FOCUSED_ORB =
 155:     gnu.CORBA.OrbFocused.class.getName();
 156:   
 157:   // There is no need for name of the default restricted ORB as it is 
 158:   // singleton and it is more effectively referred directly.
 159: 
 160:   /**
 161:    * Connect the given CORBA object to this ORB. After the object is
 162:    * connected, it starts receiving remote invocations via this ORB.
 163:    *
 164:    * The OMG group recommends to use Portable Object Adapter (POA) instead
 165:    * of calling this method.
 166:    *
 167:    * This method is implemented in the derived Gnu Classpah classes,
 168:    * returned by ORB.init(..). In this abstract class, the implementation
 169:    * just throws {@link NO_IMPLEMENT}.
 170:    *
 171:    * @param object the org.omg.CORBA.Object to connect.
 172:    */
 173:   public void connect(org.omg.CORBA.Object object)
 174:   {
 175:     throw new NO_IMPLEMENT();
 176:   }
 177: 
 178:   /**
 179:    * Disconnect the given CORBA object from this ORB. The object will be
 180:    * no longer receiving the remote invocations. In response to the
 181:    * remote invocation on this object, the ORB will send the
 182:    * exception {@link OBJECT_NOT_EXIST}. The object, however, is not
 183:    * destroyed and can receive the local invocations.
 184:    *
 185:    * This method is implemented in the derived Gnu Classpah classes,
 186:    * returned by ORB.init(..). In this abstract class, the implementation
 187:    * just throws {@link NO_IMPLEMENT}.
 188:    *
 189:    * @param object the object to disconnect.
 190:    */
 191:   public void disconnect(org.omg.CORBA.Object object)
 192:   {
 193:     throw new NO_IMPLEMENT();
 194:   }
 195: 
 196:   /**
 197:    * Create alias typecode for the given typecode.
 198:    */
 199:   public abstract TypeCode create_alias_tc(String id, String name,
 200:                                            TypeCode typecode
 201:                                           );
 202: 
 203:   /**
 204:    * Create an instance of the CORBA {@link Any} with the type, intialised
 205:    * to {@link TCKind#tk_null}
 206:    */
 207:   public abstract Any create_any();
 208: 
 209:   /**
 210:    * Create a typecode, defining an array of the given elements.
 211:    *
 212:    * @param length the size of array
 213:    * @param element_type the array component type.
 214:    *
 215:    * @return the corresponding typecode.
 216:    */
 217:   public abstract TypeCode create_array_tc(int length, TypeCode element_type);
 218: 
 219:   /**
 220:    * Creates an empty CORBA <code>ContextList</code>.
 221:    *
 222:    * @return the newly created context list.
 223:    */
 224:   public abstract ContextList create_context_list();
 225: 
 226:   /**
 227:    * The support for {@link DynAny} and derived interfaces
 228:    * has never been implemented in Sun's java releases,
 229:    * at least till v1.4 inclusive.
 230:    *
 231:    * Since v1.4 this stil missing implementation was replaced
 232:    * by the new DynamicAny package.
 233:    *
 234:    * @throws NO_IMPLEMENT, always.
 235:    */
 236:   public DynAny create_basic_dyn_any(org.omg.CORBA.TypeCode t)
 237:                               throws InconsistentTypeCode
 238:   {
 239:     throw new NO_IMPLEMENT();
 240:   }
 241:   ;
 242: 
 243:   /**
 244:    * The support for {@link DynAny} and derived interfaces
 245:    * has never been implemented in Sun's java releases,
 246:    * at least till v1.4 inclusive.
 247:    *
 248:    * Since v1.4 this stil missing implementation was replaced
 249:    * by the new DynamicAny package.
 250:    *
 251:    * @throws NO_IMPLEMENT, always.
 252:    */
 253:   public DynAny create_dyn_any(org.omg.CORBA.Any a)
 254:   {
 255:     throw new NO_IMPLEMENT();
 256:   }
 257:   ;
 258: 
 259:   /**
 260:    * The support for {@link DynArray}
 261:    * has never been implemented in Sun's java releases,
 262:    * at least till v1.4 inclusive.
 263:    *
 264:    * Since v1.4 this stil missing implementation was replaced
 265:    * by the new DynamicAny package.
 266:    *
 267:    * @throws NO_IMPLEMENT, always.
 268:    */
 269:   public DynArray create_dyn_array(org.omg.CORBA.TypeCode t)
 270:                             throws InconsistentTypeCode
 271:   {
 272:     throw new NO_IMPLEMENT();
 273:   }
 274:   ;
 275: 
 276:   /**
 277:    * The support for {@link DynEnum}
 278:    * has never been implemented in Sun's java releases,
 279:    * at least till v1.4 inclusive.
 280:    *
 281:    * Since v1.4 this stil missing implementation was replaced
 282:    * by the new DynamicAny package.
 283:    *
 284:    * @throws NO_IMPLEMENT, always.
 285:    */
 286:   public DynEnum create_dyn_enum(org.omg.CORBA.TypeCode t)
 287:                           throws InconsistentTypeCode
 288:   {
 289:     throw new NO_IMPLEMENT();
 290:   }
 291:   ;
 292: 
 293:   /**
 294:    * The support for {@link DynSequence}
 295:    * has never been implemented in Sun's java releases,
 296:    * at least till v1.4 inclusive.
 297:    *
 298:    * Since v1.4 this stil missing implementation was replaced
 299:    * by the new DynamicAny package.
 300:    *
 301:    * @throws NO_IMPLEMENT, always.
 302:    */
 303:   public DynSequence create_dyn_sequence(org.omg.CORBA.TypeCode t)
 304:                                   throws InconsistentTypeCode
 305:   {
 306:     throw new NO_IMPLEMENT();
 307:   }
 308:   ;
 309: 
 310:   /**
 311:    * The support for {@link DynStruct} and derived interfaces
 312:    * has never been implemented in Sun's java releases,
 313:    * at least till v1.4 inclusive.
 314:    *
 315:    * Since v1.4 this stil missing implementation was replaced
 316:    * by the new DynamicAny package.
 317:    *
 318:    * @throws NO_IMPLEMENT, always.
 319:    */
 320:   public DynStruct create_dyn_struct(org.omg.CORBA.TypeCode t)
 321:                               throws InconsistentTypeCode
 322:   {
 323:     throw new NO_IMPLEMENT();
 324:   }
 325:   ;
 326: 
 327:   /**
 328:    * The support for {@link DynUnion} and derived interfaces
 329:    * has never been implemented in Sun's java releases,
 330:    * at least till v1.4 inclusive.
 331:    *
 332:    * Since v1.4 this stil missing implementation was replaced
 333:    * by the new DynamicAny package.
 334:    *
 335:    * @throws NO_IMPLEMENT, always.
 336:    */
 337:   public DynUnion create_dyn_union(org.omg.CORBA.TypeCode t)
 338:                             throws InconsistentTypeCode
 339:   {
 340:     throw new NO_IMPLEMENT();
 341:   }
 342:   ;
 343: 
 344:   /**
 345:    * Create a typecode, defining the given enumeration.
 346:    *
 347:    * @param id the id.
 348:    * @param name the name.
 349:    * @param members the memebers
 350:    * @return the created enumeration.
 351:    */
 352:   public abstract TypeCode create_enum_tc(String id, String name,
 353:                                           String[] members
 354:                                          );
 355: 
 356:   /**
 357:    * Create an environment (container for exceptions).
 358:    *
 359:    * @return the created container.
 360:    */
 361:   public abstract Environment create_environment();
 362: 
 363:   /**
 364:    * Creates an empty exception list.
 365:    *
 366:    * @return the newly created list.
 367:    */
 368:   public abstract ExceptionList create_exception_list();
 369: 
 370:   /**
 371:    * Create the exception typecode.
 372:    *
 373:    * @param id the id of exception.
 374:    * @param name the name of exception.
 375:    * @param members the members of exception.
 376:    */
 377:   public abstract TypeCode create_exception_tc(String id, String name,
 378:                                                StructMember[] members
 379:                                               );
 380: 
 381:   /**
 382:    * Creates a TypeCode object for CORBA <code>fixed</code> that is
 383:    * mapped to java {@link java.math.BigDecimal}.
 384:    *
 385:    * @param digits the number of digits in that <code>fixed</code>.
 386:    * @param scale the number of digits after the decimal point.
 387:    *
 388:    * @return the corresponding TypeCode.
 389:    */
 390:   public TypeCode create_fixed_tc(short digits, short scale)
 391:   {
 392:     FixedTypeCode r = new FixedTypeCode();
 393:     r.setDigits(digits);
 394:     r.setScale(scale);
 395:     return r;
 396:   }
 397: 
 398:   /**
 399:    * Creates a typecode, representing the IDL interface.
 400:    *
 401:    * @param id the interface repository id.
 402:    * @param name the interface name.
 403:    *
 404:    * @return the created typecode.
 405:    */
 406:   public abstract TypeCode create_interface_tc(String id, String name);
 407: 
 408:   /**
 409:    * Create an instance of a new {@link NVList}.
 410:    *
 411:    * @param count the initial size of the list. If more elements are added,
 412:    * the list automatically expands.
 413:    *
 414:    * @return the created list.
 415:    */
 416:   public abstract NVList create_list(int count);
 417: 
 418:   /**
 419:    * Create a new named value.
 420:    *
 421:    * @param name the name of the named value
 422:    * @param any the content of the named value.
 423:    * @param flags the flags of the named value
 424:    *
 425:    * @return the named value.
 426:    */
 427:   public abstract NamedValue create_named_value(String name, Any any, int flags);
 428: 
 429:   /**
 430:    * Send multiple prepared requests one way, do not caring about the answer.
 431:    * The messages, containing requests, will be marked, indicating that
 432:    * the sender is not expecting to get a reply.
 433:    *
 434:    * @param requests the prepared array of requests.
 435:    *
 436:    * @see Request#send_oneway()
 437:    */
 438:   public abstract void send_multiple_requests_oneway(Request[] requests);
 439: 
 440:   /**
 441:    * Send multiple prepared requests expecting to get a reply. All requests
 442:    * are send in parallel, each in its own separate thread. When the
 443:    * reply arrives, it is stored in the agreed fields of the corresponing
 444:    * request data structure. If this method is called repeatedly,
 445:    * the new requests are added to the set of the currently sent requests,
 446:    * but the old set is not discarded.
 447:    *
 448:    * @param requests the prepared array of requests.
 449:    *
 450:    * @see #poll_next_response()
 451:    * @see #get_next_response()
 452:    * @see Request#send_deferred()
 453:    */
 454:   public abstract void send_multiple_requests_deferred(Request[] requests);
 455: 
 456:   /**
 457:    * Find if any of the requests that have been previously sent with
 458:    * {@link #send_multiple_requests_deferred}, have a response yet.
 459:    *
 460:    * @return true if there is at least one response to the previously
 461:    * sent request, false otherwise.
 462:    */
 463:   public abstract boolean poll_next_response();
 464: 
 465:   /**
 466:    * Get the next instance with a response being received. If all currently
 467:    * sent responses not yet processed, this method pauses till at least one of
 468:    * them is complete. If there are no requests currently sent, the method
 469:    * pauses till some request is submitted and the response is received.
 470:    * This strategy is identical to the one accepted by Suns 1.4 ORB
 471:    * implementation.
 472:    *
 473:    * @return the previously sent request that now contains the received
 474:    * response.
 475:    *
 476:    * @throws WrongTransaction If the method was called from the transaction
 477:    * scope different than the one, used to send the request. The exception
 478:    * can be raised only if the request is implicitly associated with some
 479:    * particular transaction.
 480:    */
 481:   public abstract Request get_next_response()
 482:                                      throws WrongTransaction;
 483: 
 484:   /**
 485:    * Create a new CDR output stream, where the parameter values can be written
 486:    * during the method invocation.
 487:    *
 488:    * @return a stream to write values into.
 489:    */
 490:   public abstract org.omg.CORBA.portable.OutputStream create_output_stream();
 491: 
 492:   /**
 493:    * This should create the list, initialised with the argument descriptions
 494:    * for the given operation definition (CORBA <code>OperationDef</code>).
 495:    * The information should be obtained from the interface repository.
 496:    * However this method is oficially documented as not implemented at least
 497:    * till v1.4 inclusive.
 498:    *
 499:    * @param operation_definition the operation definition, must be
 500:    * CORBA <code>OperationDef</code>.
 501:    *
 502:    * @return never
 503:    *
 504:    * @throws NO_IMPLEMENT, always.
 505:    */
 506:   public NVList create_operation_list(Object operation_definition)
 507:   {
 508:     throw new NO_IMPLEMENT();
 509:   }
 510: 
 511:   /**
 512:    * <p>Creates the new policy of the specified type, having the given value.
 513:    * This method looks for the policy factory that was previously registered
 514:    * during ORB initialization by
 515:    * {@link org.omg.PortableInterceptor#ORBInitialiser}.
 516:    *
 517:    * If the suitable factory is found, this factory creates the requested policy,
 518:    * otherwise the PolicyError is thrown.
 519:    * </p><p>
 520:    * The POA policies should be created by POA, not by this method.
 521:    * </p>
 522:    * @param type the policy type.
 523:    * @param value the policy value, wrapped into Any.
 524:    *
 525:    * @throws PolicyError if the ORB fails to instantiate the policy object.
 526:    *
 527:    * @throws NO_IMPLEMENT always (in this class). Overridden in derived classes
 528:    * returned by ORB.init(..).
 529:    *
 530:    * @see org.omg.PortableInterceptor.ORBInitInfoOperations#register_policy_factory
 531:    * @see org.omg.PortableInterceptor.PolicyFactoryOperations
 532:    */
 533:   public Policy create_policy(int type, Any value)
 534:                        throws PolicyError
 535:   {
 536:     throw new NO_IMPLEMENT();
 537:   }
 538: 
 539:   /**
 540:    * Create typecode, defining the sequence of the elements, having
 541:    * the given type.
 542:    *
 543:    * @param bound the maximal length of the sequence, 0 if not restricted.
 544:    *
 545:    * @param element_type the sequence element type.
 546:    *
 547:    * @return the typecode.
 548:    */
 549:   public abstract TypeCode create_sequence_tc(int bound, TypeCode element_type);
 550: 
 551:   /**
 552:    * Create a TypeCode, representing the CORBA <code>string</code>.
 553:    *
 554:    * @param bound the maximal length of the string, 0 is unlimited.
 555:    *
 556:    * @return the corresponding string typecode.
 557:    */
 558:   public abstract TypeCode create_string_tc(int bound);
 559: 
 560:   /**
 561:    * Create the typecode, defining the given IDL structure.
 562:    *
 563:    * The TypeCode object is initialized with the given id, name, and members.
 564:    * @param id the Id of this type.
 565:    * @param name the name of this type.
 566:    * @param members the member list.
 567:    *
 568:    * @return the typecode.
 569:    */
 570:   public abstract TypeCode create_struct_tc(String id, String name,
 571:                                             StructMember[] members
 572:                                            );
 573: 
 574:   /**
 575:    * Create the typecode, defining the given IDL union.
 576:    *
 577:    * The TypeCode object is initialized with the given id, name, discriminator
 578:    * and members.
 579:    *
 580:    * @param id the Id of this type.
 581:    * @param name the name of this type.
 582:    * @param discriminator the union discriminator.
 583:    * @param members the member list.
 584:    *
 585:    * @return the typecode.
 586:    */
 587:   public abstract TypeCode create_union_tc(String id, String name,
 588:                                            TypeCode discriminator,
 589:                                            UnionMember[] members
 590:                                           );
 591: 
 592:   /**
 593:    * Create a TypeCode, representing the CORBA <code>wstring</code>.
 594:    *
 595:    * @param bound the maximal length of the string, 0 is unlimited.
 596:    *
 597:    * @return the corresponding string typecode.
 598:    */
 599:   public abstract TypeCode create_wstring_tc(int bound);
 600: 
 601:   /**
 602:    * Create a typecode for an abstract interface. The abstract interface
 603:    * can be either CORBA object or CORBA value type.
 604:    *
 605:    * @param id the id of the abstract interface.
 606:    * @param name the name of the abstract interface.
 607:    *
 608:    * @return the created typecode.
 609:    */
 610:   public TypeCode create_abstract_interface_tc(String id, String name)
 611:   {
 612:     GeneralTypeCode t = new GeneralTypeCode(TCKind.tk_abstract_interface);
 613:     t.setName(name);
 614:     t.setId(id);
 615:     return t;
 616:   }
 617: 
 618:   /**
 619:    * Create a typecode for a native interface.
 620:    *
 621:    * @param id the id of the native interface.
 622:    * @param name the name of the native interface.
 623:    *
 624:    * @return the created typecode.
 625:    */
 626:   public TypeCode create_native_tc(String id, String name)
 627:   {
 628:     GeneralTypeCode t = new GeneralTypeCode(TCKind.tk_native);
 629:     t.setName(name);
 630:     t.setId(id);
 631:     return t;
 632:   }
 633: 
 634:   /**
 635:    * Create a typecode, representing a tree-like structure.
 636:    * This structure contains a member that is a sequence of the same type,
 637:    * as the structure itself. You can imagine as if the folder definition
 638:    * contains a variable-length array of the enclosed (nested) folder
 639:    * definitions. In this way, it is possible to have a tree like
 640:    * structure that can be transferred via CORBA CDR stream.
 641:    *
 642:    * @deprecated It is easier and clearler to use a combination of
 643:    * create_recursive_tc and create_sequence_tc instead.
 644:    *
 645:    * @param bound the maximal expected number of the nested components
 646:    * on each node; 0 if not limited.
 647:    *
 648:    * @param offset the position of the field in the returned structure
 649:    * that contains the sequence of the structures of the same field.
 650:    * The members before this field are intialised using parameterless
 651:    * StructMember constructor.
 652:    *
 653:    * @return a typecode, defining a stucture, where a member at the
 654:    * <code>offset</code> position defines an array of the identical
 655:    * structures.
 656:    *
 657:    * @see #create_recursive_tc(String)
 658:    * @see #create_sequence_tc(int, TypeCode)
 659:    */
 660:   public TypeCode create_recursive_sequence_tc(int bound, int offset)
 661:   {
 662:     RecordTypeCode r = new RecordTypeCode(TCKind.tk_struct);
 663:     for (int i = 0; i < offset; i++)
 664:       r.add(new StructMember());
 665: 
 666:     TypeCode recurs = new PrimitiveTypeCode(TCKind.tk_sequence);
 667: 
 668:     r.add(new StructMember("", recurs, null));
 669:     return r;
 670:   }
 671: 
 672:   /**
 673:    * Create a typecode which serves as a placeholder for typcode, containing
 674:    * recursion.
 675:    *
 676:    * @param id the id of the recursive typecode, for that this typecode
 677:    * serves as a placeholder.
 678:    */
 679:   public TypeCode create_recursive_tc(String id)
 680:   {
 681:     return new RecursiveTypeCode(id);
 682:   }
 683: 
 684:   /**
 685:    * Create value box typecode.
 686:    */
 687:   public TypeCode create_value_box_tc(String id, String name,
 688:                                       TypeCode boxed_type
 689:                                      )
 690:   {
 691:     GeneralTypeCode t = new GeneralTypeCode(TCKind.tk_value_box);
 692:     t.setName(name);
 693:     t.setId(id);
 694:     t.setContentType(boxed_type);
 695:     return t;
 696:   }
 697: 
 698:   /**
 699:    * Create IDL value type code.
 700:    */
 701:   public TypeCode create_value_tc(String id, String name, short type_modifier,
 702:                                   TypeCode concrete_base, ValueMember[] members
 703:                                  )
 704:   {
 705:     RecordTypeCode r = new RecordTypeCode(TCKind.tk_value);
 706:     r.setId(id);
 707:     r.setName(name);
 708:     r.setTypeModifier(type_modifier);
 709:     r.setConcreteBase_type(concrete_base);
 710: 
 711:     for (int i = 0; i < members.length; i++)
 712:       {
 713:         r.add(members [ i ]);
 714:       }
 715: 
 716:     return r;
 717:   }
 718: 
 719:   /**
 720:    * This should return the information, related to the current thread.
 721:    * The information is needed, for instance, to get the current object
 722:    * from the code that serves several objects in parallel threads.
 723:    * The {@link Current} is very general interface, with no fields and
 724:    * operations defined. This method is not implemented in Suns
 725:    * releases at least till v1.5 inclusive. To obtain the
 726:    * {@link org.omg.PortableServer.Current}, use
 727:    * {@link #resolve_initial_references}, passing "POACurrent".
 728:    *
 729:    * @deprecated since 1.2, use {@link #resolve_initial_references}.
 730:    *
 731:    * @return never
 732:    *
 733:    * @throws NO_IMPLEMENT always.
 734:    */
 735:   public Current get_current()
 736:   {
 737:     throw new NO_IMPLEMENT();
 738:   }
 739: 
 740:   /**
 741:    * This should return the information about the CORBA facilities and
 742:    * services, available from this ORB. However this method is oficially
 743:    * documented as not implemented at least till v1.5 inclusive.
 744:    *
 745:    * @param service_type a type of the service being requested. The OMG
 746:    * specification currently defines only one value, 1, for security
 747:    * related services.
 748:    *
 749:    * @param service_info a holder, where the returned information should
 750:    * be stored.
 751:    *
 752:    * @return should return true if the service information is available
 753:    * from the ORB, but this method never returns.
 754:    *
 755:    * @throws NO_IMPLEMENT always.
 756:    */
 757:   public boolean get_service_information(short service_type,
 758:                                          ServiceInformationHolder service_info
 759:                                         )
 760:   {
 761:     throw new NO_IMPLEMENT();
 762:   }
 763: 
 764:   /**
 765:    * Get the default context of this ORB. This is an initial root of all
 766:    * contexts.
 767:    *
 768:    * The default method returns a new context with the empty name and
 769:    * no parent context.
 770:    *
 771:    * @return the default context of this ORB.
 772:    *
 773:    * @throws NO_IMPLEMENT for the Singleton ORB, returned by
 774:    * the parameterless {@link #init()}.
 775:    */
 776:   public Context get_default_context()
 777:   {
 778:     return new gnuContext("", null);
 779:   }
 780: 
 781:   /**
 782:    * Return thg typecode, representing the given primitive object type.
 783:    *
 784:    * @param tcKind the kind of the primitive typecode.
 785:    *
 786:    * @return the typecode of the primitve typecode.
 787:    */
 788:   public abstract TypeCode get_primitive_tc(TCKind tcKind);
 789: 
 790:   /**
 791:    * Returns so-called Singleton ORB, a highly restricted version
 792:    * that cannot communicate over network. This ORB is provided
 793:    * for the potentially malicious applets with heavy security restrictions.
 794:    *
 795:    * The returned Singleton ORB can only create typecodes,
 796:    * {@link Any}, {@link ContextList}, {@link NVList} and
 797:    * {@link org.omg.CORBA.portable.OutputStream} that writes to an
 798:    * internal buffer.
 799:    *
 800:    * All other methods throw the {@link NO_IMPLEMENT} exception, additionally
 801:    * printing the error message about the potential attempt to violate
 802:    * the security rules.
 803:    *
 804:    * The implementing ORB class, used in this method, is found as described
 805:    * in the header.
 806:    *
 807:    * @return the working derivative of ORB, implementing the methods
 808:    * of this abstract class.
 809:    */
 810:   public static ORB init()
 811:   {
 812:     String orb_cn = getCumulatedProperty(null, RESTRICTED_ORB);
 813:     if (orb_cn == null)
 814:       return OrbRestricted.Singleton;
 815:     else
 816:       return createORB(null, orb_cn);
 817:   }
 818: 
 819:   /**
 820:    * Creates the working instance of ORB for an applet.
 821:    *
 822:    * By default the built-in fully functional ORB is returned. The ORB class
 823:    * is found as described in the header of this class.
 824:    *
 825:    * @param applet the applet. The property org.omg.CORBA.ORBClass,
 826:    * if present, defines the used ORB implementation class. If this
 827:    * property is not present, the ORB class is found as described in the
 828:    * class header.
 829:    *
 830:    * @param props the properties, may be <code>null</code>.
 831:    *
 832:    * @return a newly created functional derivative of this abstract class.
 833:    */
 834:   public static ORB init(Applet applet, Properties props)
 835:   {
 836:     String ocn = applet.getParameter(FUNCTIONAL_ORB);
 837:     String lp = applet.getParameter(LISTENER_PORT);
 838:     
 839:     if (ocn==null && lp!=null)
 840:       ocn = DEFAULT_FOCUSED_ORB;
 841:     
 842:     ORB orb = createORB(props, ocn);
 843:     orb.set_parameters(applet, props);
 844: 
 845:     return orb;
 846:   }
 847: 
 848:   /**
 849:    * Creates the working instance of ORB for a standalone application.
 850:    * 
 851:    * By default the built-in fully functional ORB is returned. The ORB class is
 852:    * found as described in the header of this class.
 853:    * 
 854:    * @param args the parameters, passed to the applications
 855:    * <code>main(String[] args)</code> method, may be <code>null</code>. The
 856:    * parameter -org.omg.CORBA.ORBClass <class name> if present, defines the used
 857:    * ORB implementation class. If this property is not present, the ORB class is
 858:    * found as described in the class header.
 859:    * 
 860:    * @param props application specific properties, may be <code>null</code>.
 861:    * 
 862:    * @return a newly created functional derivative of this abstract class.
 863:    */
 864:   public static ORB init(String[] args, Properties props)
 865:   {
 866:     String ocn = null;
 867:     String lp = null;
 868: 
 869:     String orbKey = "-" + FUNCTIONAL_ORB;
 870:     String lpKey = "-" + LISTENER_PORT;
 871: 
 872:     if (args != null)
 873:       if (args.length >= 2)
 874:         {
 875:           for (int i = 0; i < args.length - 1; i++)
 876:             {
 877:               if (args[i].equals(orbKey))
 878:                 ocn = args[i + 1];
 879:               if (args[i].equals(lpKey))
 880:                 lp = args[i + 1];
 881:             }
 882:         }
 883: 
 884:     if (lp != null && ocn == null)
 885:       ocn = DEFAULT_FOCUSED_ORB;
 886: 
 887:     ORB orb = createORB(props, ocn);
 888: 
 889:     orb.set_parameters(args, props);
 890:     return orb;
 891:   }
 892: 
 893:   /**
 894:    * List the initially available CORBA objects (services).
 895:    * 
 896:    * @return a list of services.
 897:    * 
 898:    * @see #resolve_initial_references(String)
 899:    */
 900:   public abstract String[] list_initial_services();
 901: 
 902:   /**
 903:    * Find and return the easily accessible CORBA object, addressed
 904:    * by name.  The returned object is typically casted to the more
 905:    * specific reference using the <code>narrow(Object)</code> method
 906:    * of its helper. The method resolves the following string values,
 907:    * returning the working objects:
 908:    * <table border="1"><tr><th>String</th><th>Object class</th>
 909:    * <th>Object use</th></tr>
 910:    *
 911:    * <tr><td>NameService</td><td>{@link org.omg.CosNaming.NamingContextExt}</td>
 912:    * <td>Finds (usually remote) object by its name.</td></tr>
 913:    *
 914:    * <tr><td>RootPOA</td><td>{@link org.omg.PortableServer.POA}</td>
 915:    * <td>Holds the POA tree for this ORB, where since 1.4 all servants
 916:    * should be connected.</td></tr>
 917:    *
 918:    * <tr><td>RootPOAManager</td><td>{@link org.omg.PortableServer.POAManager}
 919:    * </td><td>Regulates (suspends/resumes) the root POA
 920:    * activity</td></tr>
 921:    *
 922:    * <tr><td>POACurrent</td><td>{@link org.omg.PortableServer.Current}
 923:    * </td><td>Informs the current thread about the Id and POA of the
 924:    * object being currently served (the methods of
 925:    * <code>Current</code> return different values for
 926:    * different threads).
 927:    * </td></tr>
 928:    *
 929:    * <tr><td>CodecFactory</td><td>{@link org.omg.IOP.Codec}</td>
 930:    * <td>Encodes/decodes IDL data types into/from byte arrays.</td>
 931:    * </tr>
 932:    *
 933:    * <tr><td>DynAnyFactory</td><td>{@link org.omg.DynamicAny.DynAnyFactory}</td>
 934:    * <td>Creates DynAny's.</td>
 935:    * </tr>
 936:    *
 937:    * <tr><td>PICurrent</td><td>{@link org.omg.PortableInterceptor.Current}</td>
 938:    * <td>Contains multiple slots where an interceptor can rememeber the
 939:    * request - specific values between subsequent
 940:    * calls of the interceptor methods.</td>
 941:    * </tr>
 942:    *
 943:    * </table>
 944:    *
 945:    * @param name the object name.
 946:    * @return the object
 947:    * @throws org.omg.CORBA.ORBPackage.InvalidName if the given name
 948:    * is not associated with the known object.
 949:    */
 950:   public abstract Object resolve_initial_references(String name)
 951:     throws org.omg.CORBA.ORBPackage.InvalidName;
 952: 
 953:   /**
 954:    * Get the IOR reference string for the given object.
 955:    * IOR can be compared with the Internet address for a web page,
 956:    * it provides means to locate the CORBA service on the web.
 957:    * IOR contains the host address, port number, the object identifier
 958:    * (key) inside the server, the communication protocol version,
 959:    * supported charsets and so on.
 960:    *
 961:    * @param forObject the CORBA object
 962:    * @return the object IOR representation.
 963:    * @see #string_to_object(String)
 964:    */
 965:   public abstract String object_to_string(Object forObject);
 966: 
 967:   /**
 968:    * This should perform the implementation dependent unit of work in the
 969:    * main thread.
 970:    *
 971:    * This method is part of the support for the distribute use of the
 972:    * single execution thread.
 973:    *
 974:    * Same as in Suns releases at least till 1.4 inclusive,
 975:    * the distribute use of the single thread is not implemented.
 976:    * Use multiple threads, provided by jre.
 977:    *
 978:    * The method returns without action.
 979:    */
 980:   public void perform_work()
 981:   {
 982:   }
 983: 
 984:   /**
 985:   * Checks if the ORB needs the main thread to perform some work.
 986:   * The method should return true if the ORB needs the main thread,
 987:   * and false if it does not.
 988:   *
 989:   * This method is part of the support for the distribute use of the
 990:   * single execution thread.
 991:   *
 992:   * Same as in Suns releases at least till 1.4 inclusive,
 993:   * the distributed use of the single thread is not implemented.
 994:   * Use multiple threads, provided by jre.
 995:   *
 996:   * @return false, always.
 997:   */
 998:   public boolean work_pending()
 999:   {
1000:     return false;
1001:   }
1002: 
1003:   /**
1004:    * <p>Find and return the CORBA object, addressed by the given
1005:    * string representation. The object can be (an usually is)
1006:    * located on a remote computer, possibly running a different
1007:    * (not necessary java) CORBA implementation. The returned
1008:    * object is typically casted to the more specific reference
1009:    * using the <code>narrow(Object)</code> method of its helper.
1010:    * </p><p>
1011:    * This function supports the following input formats:<br>
1012:    * 1. IOR reference (<b>ior:</b>nnnnn ..), usually computer generated.<br> 
1013:    * 2. <b>corbaloc:</b>[<b>iiop</b>][version.subversion<b>@</b>]<b>:</b>host[<b>:</b>port]<b>/</b><i>key</i>
1014:    * defines similar information as IOR reference, but is more human readable.
1015:    * This type of reference may also contain multiple addresses (see
1016:    * OMG documentation for complete format).<br>
1017:    * 3. <b>corbaloc:rir:/</b><i>name</i> defines internal reference on this
1018:    * ORB that is resolved using {@link #resolve_initial_references}, passing 
1019:    * the given <i>name</i> as parameter.<br>
1020:    * 4. <b>corbaname:rir:#</b><i>name</i> states that the given <i>name</i>
1021:    * must be resolved using the naming service, default for this ORB.<br>
1022:    * 5. <b>corbaname:</b>[<b>iiop</b>][version.subversion<b>@</b>]<b>:</b>host[<b>:</b>port]<b>#</b><i>name</i>
1023:    * states that the <i>name</i> must be resolved using the naming service
1024:    * that runs on the given host at the given port. The ORB expects to find 
1025:    * there the {@link org.omg.CosNaming.NamingContext} under the key 
1026:    * "NameService.<br>
1027:    * 
1028:    * <p>The default port is always 2809. The default iiop version is 1.0
1029:    * that now may not always be supported, so we would recommend to specify
1030:    * the version explicitly.</p>
1031:    * <p>
1032:    * The examples of the corbaloc and corbaname addresses:<br>
1033:    * corbaname:rir:#xobj - ask local naming service for "xobj".<br>
1034:    * corbaname:rir:/NameService#xobj - same (long form).<br>
1035:    * corbaname:iiop:1.2@localhost:900#xobj - same, assuming that the naming 
1036:    * service runs at port 900 on the local host and supports iiop 1.2.<br>
1037:    * corbaname:iiop:localhost#xobj - same, assuming that the naming 
1038:    * service runs at port 2809 on the local host and supports iiop 1.0.<br>
1039:    * corbaloc::gnu.xxx.yy/Prod/TradingService - the object exists on the
1040:    * host gnu.xxx.yy, port 2809 having the key "Prod/TradingService". Its ORB 
1041:    * supports iiop 1.0.<br>
1042:    * corbaloc::gnu.xxx.yy/Prod/TradingService:801 - the object exists on the
1043:    * host gnu.xxx.yy, port 801 having the key "Prod/TradingService". Its ORB 
1044:    * supports iiop 1.0 (iiop keyword ommitted).<br>
1045:    * corbaloc:iiop:1.1@gnu.xxx.yy/Prod/TradingService - the object exists on the
1046:    * host gnu.xxx.yy, port 801 having the key "Prod/TradingService". Its ORB 
1047:    * supports iiop 1.1.<br>
1048:    * corbaloc:rir:/NameService - the default naming service.
1049:    *
1050:    * @param IOR the object IOR representation string.
1051:    *
1052:    * @return the found CORBA object.
1053:    * 
1054:    * @throws BAD_PARAM if the string being parsed is invalid.
1055:    * @throws DATA_CONVERSION if the string being parsed contains unsupported
1056:    * prefix or protocol.
1057:    * 
1058:    * @see #object_to_string(org.omg.CORBA.Object)
1059:    */
1060:   public abstract Object string_to_object(String IOR);
1061: 
1062:   /**
1063:    * Start listening on the input socket. This method
1064:    * blocks the current thread until {@link #shutdown(boolean)}
1065:    * is called and shutdown process is completed.
1066:    */
1067:   public void run()
1068:   {
1069:   }
1070: 
1071:   /**
1072:    * Shutdown the ORB server.
1073:    *
1074:    * @param wait_for_completion if true, the current thread is
1075:    * suspended untile the shutdown process is complete.
1076:    */
1077:   public void shutdown(boolean wait_for_completion)
1078:   {
1079:   }
1080: 
1081:   /**
1082:    * Destroy this server, releasing the occupied resources.
1083:    * The default method returns without action.
1084:    */
1085:   public void destroy()
1086:   {
1087:   }
1088: 
1089:   /**
1090:    * Set the ORB parameters. This method is normally called from
1091:    * {@link #init(String[], Properties)}.
1092:    *
1093:    * @param para the parameters, that were passed as the parameters
1094:    * to the  <code>main(String[] args)</code> method of the current standalone
1095:    * application.
1096:    *
1097:    * @param props application specific properties that were passed
1098:    * as a second parameter in {@link #init(String[], Properties)}).
1099:    * Can be <code>null</code>.
1100:    */
1101:   protected abstract void set_parameters(String[] para, Properties props);
1102: 
1103:   /**
1104:    * Set the ORB parameters. This method is normally called from
1105:    * {@link #init(Applet, Properties)}.
1106:    *
1107:    * @param app the current applet.
1108:    *
1109:    * @param props application specific properties, passed as the second
1110:    * parameter in {@link #init(Applet, Properties)}.
1111:    * Can be <code>null</code>.
1112:    */
1113:   protected abstract void set_parameters(Applet app, Properties props);
1114: 
1115:   /**
1116:    * Get the property with the given name, searching in the standard
1117:    * places for the ORB properties.
1118:    */
1119:   private static String getCumulatedProperty(Properties props, String property)
1120:   {
1121:     String orb_cn = null;
1122: 
1123:     if (props != null)
1124:       orb_cn = props.getProperty(property, null);
1125: 
1126:     if (orb_cn == null)
1127:       orb_cn = System.getProperty(property, null);
1128: 
1129:     if (orb_cn == null)
1130:       orb_cn = checkFile(property, "user.home", null);
1131: 
1132:     if (orb_cn == null)
1133:       orb_cn = checkFile(property, "java.home", "lib");
1134:     
1135:     return orb_cn;
1136:   }
1137: 
1138:   /**
1139:    * Check if the property is defined in the existsting file orb.properties.
1140:    *
1141:    * @param property the property
1142:    * @param dir the system property, defining the folder where the
1143:    * file could be expected.
1144:    * @param subdir subfolder where to look for the file.
1145:    *
1146:    * @return the property value, null if not found or file does not exist.
1147:    */
1148:   private static String checkFile(String property, String dir, String subdir)
1149:   {
1150:     try
1151:       {
1152:         File f = new File(dir);
1153:         if (!f.exists())
1154:           return null;
1155: 
1156:         if (subdir != null)
1157:           f = new File(f, subdir);
1158: 
1159:         f = new File(f, "orb.properties");
1160: 
1161:         if (!f.exists())
1162:           return null;
1163: 
1164:         Properties p = new Properties();
1165:         p.load(new BufferedInputStream(new FileInputStream(f)));
1166: 
1167:         return p.getProperty(property, null);
1168:       }
1169:     catch (IOException ex)
1170:       {
1171:         return null;
1172:       }
1173:   }
1174: 
1175:   /**
1176:    * Create ORB when its name is possibly known.
1177:    * 
1178:    * @param props properties, possibly containing the ORB name.
1179:    * @param orbClassName the direct ORB class name, overriding other possible
1180:    * locations, or null if not specified.
1181:    */
1182:   private static ORB createORB(Properties props, String orbClassName)
1183:   {
1184:     ORB orb = null;
1185: 
1186:     if (orbClassName == null)
1187:       {
1188:         orbClassName = getCumulatedProperty(props, FUNCTIONAL_ORB);
1189: 
1190:         if (orbClassName == null)
1191:           {
1192:             String lp = getCumulatedProperty(props, LISTENER_PORT);
1193:             if (lp != null)
1194:               orbClassName = DEFAULT_FOCUSED_ORB;
1195:             else
1196:               orbClassName = DEFAULT_FUNCTIONAL_ORB;
1197:           }
1198:       }
1199: 
1200:     try
1201:       {
1202:         orb = (ORB) ObjectCreator.forName(orbClassName).newInstance();
1203:       }
1204:     catch (ClassNotFoundException ex)
1205:       {
1206:         noORB(orbClassName, ex);
1207:       }
1208:     catch (IllegalAccessException ex)
1209:       {
1210:         noORB(orbClassName, ex);
1211:       }
1212:     catch (InstantiationException ex)
1213:       {
1214:         noORB(orbClassName, ex);
1215:       }
1216: 
1217:     return orb;
1218:   }
1219: 
1220:   /**
1221:    * Throw the runtime exception.
1222:    *
1223:    * @param orb_c the ORB class name.
1224:    * @param why the explaining chained exception.
1225:    */
1226:   private static void noORB(String orb_c, Throwable why)
1227:   {
1228:     throw new RuntimeException("The ORB " + orb_c + " cannot be instantiated.",
1229:                                why
1230:                               );
1231:   }