1 /*
   2  * Copyright (c) 1997, 2006, 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 package org.omg.CORBA.portable;
  26 
  27 import org.omg.CORBA.Request;
  28 import org.omg.CORBA.NamedValue;
  29 import org.omg.CORBA.NVList;
  30 import org.omg.CORBA.ExceptionList;
  31 import org.omg.CORBA.ContextList;
  32 import org.omg.CORBA.Context;
  33 import org.omg.CORBA.TypeCode;
  34 import org.omg.CORBA.BAD_OPERATION;
  35 import org.omg.CORBA.SystemException;
  36 
  37 
  38 /**
  39  *  The common base class for all stub classes; provides default implementations
  40  *  of the <code>org.omg.CORBA.Object</code> methods. All method implementations are
  41  *  forwarded to a <code>Delegate</code> object stored in the <code>ObjectImpl</code>
  42  *  instance.  <code>ObjectImpl</code> allows for portable stubs because the
  43  *  <code>Delegate</code> can be implemented by a different vendor-specific ORB.
  44  */
  45 
  46 abstract public class ObjectImpl implements org.omg.CORBA.Object
  47 {
  48 
  49     /**
  50      * The field that stores the <code>Delegate</code> instance for
  51      * this <code>ObjectImpl</code> object. This <code>Delegate</code>
  52      * instance can be implemented by a vendor-specific ORB.  Stub classes,
  53      * which are derived from this <code>ObjectImpl</code> class, can be
  54      * portable because they delegate all of the methods called on them to this
  55      * <code>Delegate</code> object.
  56      */
  57     private transient Delegate __delegate;
  58 
  59 
  60     /**
  61      * Retrieves the reference to the vendor-specific <code>Delegate</code>
  62      * object to which this <code>ObjectImpl</code> object delegates all
  63      * methods invoked on it.
  64      *
  65      * @return the Delegate contained in this ObjectImpl instance
  66      * @throws BAD_OPERATION if the delegate has not been set
  67      * @see #_set_delegate
  68      */
  69     public Delegate _get_delegate() {
  70         if (__delegate == null)
  71             throw new BAD_OPERATION("The delegate has not been set!");
  72         return __delegate;
  73     }
  74 
  75 
  76     /**
  77      * Sets the Delegate for this <code>ObjectImpl</code> instance to the given
  78      * <code>Delegate</code> object.  All method invocations on this
  79      * <code>ObjectImpl</code> object will be forwarded to this delegate.
  80      *
  81      * @param delegate the <code>Delegate</code> instance to which
  82      *        all method calls on this <code>ObjectImpl</code> object
  83      *        will be delegated; may be implemented by a third-party ORB
  84      * @see #_get_delegate
  85      */
  86     public void _set_delegate(Delegate delegate) {
  87         __delegate = delegate;
  88     }
  89 
  90     /**
  91      * Retrieves a string array containing the repository identifiers
  92      * supported by this <code>ObjectImpl</code> object.  For example,
  93      * for a stub, this method returns information about all the
  94      * interfaces supported by the stub.
  95      *
  96      * @return the array of all repository identifiers supported by this
  97      *         <code>ObjectImpl</code> instance
  98      */
  99     public abstract String[] _ids();
 100 
 101 
 102     /**
 103      * Returns a duplicate of this <code>ObjectImpl</code> object.
 104      *
 105      * @return an <code>orb.omg.CORBA.Object</code> object that is
 106      *         a duplicate of this object
 107      */
 108     public org.omg.CORBA.Object _duplicate() {
 109         return _get_delegate().duplicate(this);
 110     }
 111 
 112     /**
 113      * Releases the resources associated with this <code>ObjectImpl</code> object.
 114      */
 115     public void _release() {
 116         _get_delegate().release(this);
 117     }
 118 
 119     /**
 120      * Checks whether the object identified by the given repository
 121      * identifier is an <code>ObjectImpl</code> object.
 122      *
 123      * @param repository_id a <code>String</code> object with the repository
 124      *        identifier to check
 125      * @return <code>true</code> if the object identified by the given
 126      *         repository id is an instance of <code>ObjectImpl</code>;
 127      *         <code>false</code> otherwise
 128      */
 129     public boolean _is_a(String repository_id) {
 130         return _get_delegate().is_a(this, repository_id);
 131     }
 132 
 133     /**
 134      * Checks whether the the given <code>ObjectImpl</code> object is
 135      * equivalent to this <code>ObjectImpl</code> object.
 136      *
 137      * @param that an instance of <code>ObjectImpl</code> to compare with
 138      *        this <code>ObjectImpl</code> object
 139      * @return <code>true</code> if the given object is equivalent
 140      *         to this <code>ObjectImpl</code> object;
 141      *         <code>false</code> otherwise
 142      */
 143     public boolean _is_equivalent(org.omg.CORBA.Object that) {
 144         return _get_delegate().is_equivalent(this, that);
 145     }
 146 
 147     /**
 148      * Checks whether the server object for this <code>ObjectImpl</code>
 149      * object has been destroyed.
 150      *
 151      * @return <code>true</code> if the ORB knows authoritatively that the
 152      *         server object does not exist; <code>false</code> otherwise
 153      */
 154     public boolean _non_existent() {
 155         return _get_delegate().non_existent(this);
 156     }
 157 
 158     /**
 159      * Retrieves the hash code that serves as an ORB-internal identifier for
 160      * this <code>ObjectImpl</code> object.
 161      *
 162      * @param maximum an <code>int</code> indicating the upper bound on the hash
 163      *        value returned by the ORB
 164      * @return an <code>int</code> representing the hash code for this
 165      *         <code>ObjectImpl</code> object
 166      */
 167     public int _hash(int maximum) {
 168         return _get_delegate().hash(this, maximum);
 169     }
 170 
 171     /**
 172      * Creates a <code>Request</code> object containing the given method
 173      * that can be used with the Dynamic Invocation Interface.
 174      *
 175      * @param operation the method to be invoked by the new <code>Request</code>
 176      *        object
 177      * @return a new <code>Request</code> object initialized with the
 178      *         given method
 179      */
 180     public Request _request(String operation) {
 181         return _get_delegate().request(this, operation);
 182     }
 183 
 184     /**
 185      * Creates a <code>Request</code> object that contains the given context,
 186      * method, argument list, and container for the result.
 187      *
 188      * @param ctx the Context for the request
 189      * @param operation the method that the new <code>Request</code>
 190      *        object will invoke
 191      * @param arg_list the arguments for the method; an <code>NVList</code>
 192      *        in which each argument is a <code>NamedValue</code> object
 193      * @param result a <code>NamedValue</code> object to be used for
 194      *        returning the result of executing the request's method
 195      * @return a new <code>Request</code> object initialized with the
 196      *         given context, method, argument list, and container for the
 197      *         return value
 198      */
 199     public Request _create_request(Context ctx,
 200                                    String operation,
 201                                    NVList arg_list,
 202                                    NamedValue result) {
 203         return _get_delegate().create_request(this,
 204                                               ctx,
 205                                               operation,
 206                                               arg_list,
 207                                               result);
 208     }
 209 
 210     /**
 211      * Creates a <code>Request</code> object that contains the given context,
 212      * method, argument list, container for the result, exceptions, and
 213      * list of property names to be used in resolving the context strings.
 214      * This <code>Request</code> object is for use in the Dynamic
 215      * Invocation Interface.
 216      *
 217      * @param ctx the <code>Context</code> object that contains the
 218      *        context strings that must be resolved before they are
 219      *        sent along with the request
 220      * @param operation the method that the new <code>Request</code>
 221      *        object will invoke
 222      * @param arg_list the arguments for the method; an <code>NVList</code>
 223      *        in which each argument is a <code>NamedValue</code> object
 224      * @param result a <code>NamedValue</code> object to be used for
 225      *        returning the result of executing the request's method
 226      * @param exceptions a list of the exceptions that the given method
 227      *        throws
 228      * @param contexts a list of the properties that are needed to
 229      *        resolve the contexts in <i>ctx</i>; the strings in
 230      *        <i>contexts</i> are used as arguments to the method
 231      *        <code>Context.get_values</code>,
 232      *        which returns the value associated with the given property
 233      * @return a new <code>Request</code> object initialized with the
 234      *         given context strings to resolve, method, argument list,
 235      *         container for the result, exceptions, and list of property
 236      *         names to be used in resolving the context strings
 237      */
 238     public Request _create_request(Context ctx,
 239                                    String operation,
 240                                    NVList arg_list,
 241                                    NamedValue result,
 242                                    ExceptionList exceptions,
 243                                    ContextList contexts) {
 244         return _get_delegate().create_request(this,
 245                                               ctx,
 246                                               operation,
 247                                               arg_list,
 248                                               result,
 249                                               exceptions,
 250                                               contexts);
 251     }
 252 
 253     /**
 254      * Retrieves the interface definition for this <code>ObjectImpl</code>
 255      * object.
 256      *
 257      * @return the <code>org.omg.CORBA.Object</code> instance that is the
 258      *         interface definition for this <code>ObjectImpl</code> object
 259      */
 260     public org.omg.CORBA.Object _get_interface_def()
 261     {
 262         // First try to call the delegate implementation class's
 263         // "Object get_interface_def(..)" method (will work for JDK1.2 ORBs).
 264         // Else call the delegate implementation class's
 265         // "InterfaceDef get_interface(..)" method using reflection
 266         // (will work for pre-JDK1.2 ORBs).
 267 
 268         org.omg.CORBA.portable.Delegate delegate = _get_delegate();
 269         try {
 270             // If the ORB's delegate class does not implement
 271             // "Object get_interface_def(..)", this will call
 272             // get_interface_def(..) on portable.Delegate.
 273             return delegate.get_interface_def(this);
 274         }
 275         catch( org.omg.CORBA.NO_IMPLEMENT ex ) {
 276             // Call "InterfaceDef get_interface(..)" method using reflection.
 277             try {
 278                 Class[] argc = { org.omg.CORBA.Object.class };
 279                 java.lang.reflect.Method meth =
 280                     delegate.getClass().getMethod("get_interface", argc);
 281                 Object[] argx = { this };
 282                 return (org.omg.CORBA.Object)meth.invoke(delegate, argx);
 283             }
 284             catch( java.lang.reflect.InvocationTargetException exs ) {
 285                 Throwable t = exs.getTargetException();
 286                 if (t instanceof Error) {
 287                     throw (Error) t;
 288                 }
 289                 else if (t instanceof RuntimeException) {
 290                     throw (RuntimeException) t;
 291                 }
 292                 else {
 293                     throw new org.omg.CORBA.NO_IMPLEMENT();
 294                 }
 295             } catch( RuntimeException rex ) {
 296                 throw rex;
 297             } catch( Exception exr ) {
 298                 throw new org.omg.CORBA.NO_IMPLEMENT();
 299             }
 300         }
 301     }
 302 
 303     /**
 304      * Returns a reference to the ORB associated with this object and
 305      * its delegate.  This is the <code>ORB</code> object that created
 306      * the delegate.
 307      *
 308      * @return the <code>ORB</code> instance that created the
 309      *          <code>Delegate</code> object contained in this
 310      *          <code>ObjectImpl</code> object
 311      */
 312     public org.omg.CORBA.ORB _orb() {
 313         return _get_delegate().orb(this);
 314     }
 315 
 316 
 317     /**
 318      * Retrieves the <code>Policy</code> object for this
 319      * <code>ObjectImpl</code> object that has the given
 320      * policy type.
 321      *
 322      * @param policy_type an int indicating the policy type
 323      * @return the <code>Policy</code> object that is the specified policy type
 324      *         and that applies to this <code>ObjectImpl</code> object
 325      * @see org.omg.CORBA.PolicyOperations#policy_type
 326      */
 327     public org.omg.CORBA.Policy _get_policy(int policy_type) {
 328         return _get_delegate().get_policy(this, policy_type);
 329     }
 330 
 331     /**
 332      * Retrieves a list of the domain managers for this
 333      * <code>ObjectImpl</code> object.
 334      *
 335      * @return an array containing the <code>DomainManager</code>
 336      *         objects for this instance of <code>ObjectImpl</code>
 337      */
 338     public org.omg.CORBA.DomainManager[] _get_domain_managers() {
 339         return _get_delegate().get_domain_managers(this);
 340     }
 341 
 342     /**
 343      * Sets this <code>ObjectImpl</code> object's override type for
 344      * the given policies to the given instance of
 345      * <code>SetOverrideType</code>.
 346      *
 347      * @param policies an array of <code>Policy</code> objects with the
 348      *         policies that will replace the current policies or be
 349      *         added to the current policies
 350      * @param set_add either <code>SetOverrideType.SET_OVERRIDE</code>,
 351      *         indicating that the given policies will replace any existing
 352      *         ones, or <code>SetOverrideType.ADD_OVERRIDE</code>, indicating
 353      *         that the given policies should be added to any existing ones
 354      * @return an <code>Object</code> with the given policies replacing or
 355      *         added to its previous policies
 356      */
 357     public org.omg.CORBA.Object
 358         _set_policy_override(org.omg.CORBA.Policy[] policies,
 359                              org.omg.CORBA.SetOverrideType set_add) {
 360         return _get_delegate().set_policy_override(this, policies,
 361                                                    set_add);
 362     }
 363 
 364     /**
 365      * Checks whether this <code>ObjectImpl</code> object is implemented
 366      * by a local servant.  If so, local invocation API's may be used.
 367      *
 368      * @return <code>true</code> if this object is implemented by a local
 369      *         servant; <code>false</code> otherwise
 370      */
 371     public boolean _is_local() {
 372         return _get_delegate().is_local(this);
 373     }
 374 
 375     /**
 376      * Returns a Java reference to the local servant that should be used for sending
 377      * a request for the method specified. If this <code>ObjectImpl</code>
 378      * object is a local stub, it will invoke the <code>_servant_preinvoke</code>
 379      * method before sending a request in order to obtain the
 380      * <code>ServantObject</code> instance to use.
 381      * <P>
 382      * If a <code>ServantObject</code> object is returned, its <code>servant</code>
 383      * field has been set to an object of the expected type (Note: the object may
 384      * or may not be the actual servant instance). The local stub may cast
 385      * the servant field to the expected type, and then invoke the operation
 386      * directly. The <code>ServantRequest</code> object is valid for only one
 387      * invocation and cannot be used for more than one invocation.
 388      *
 389      * @param operation a <code>String</code> containing the name of the method
 390      *        to be invoked. This name should correspond to the method name as
 391      *        it would be encoded in a GIOP request.
 392      *
 393      * @param expectedType a <code>Class</code> object representing the
 394      *        expected type of the servant that is returned. This expected
 395      *        type is the <code>Class</code> object associated with the
 396      *        operations class for the stub's interface. For example, a
 397      *        stub for an interface <code>Foo</code> would pass the
 398      *        <code>Class</code> object for the <code>FooOperations</code>
 399      *        interface.
 400      *
 401      * @return (1) a <code>ServantObject</code> object, which may or may
 402      *         not be the actual servant instance, or (2) <code>null</code> if
 403      *         (a) the servant is not local or (b) the servant has ceased to
 404      *         be local due to a ForwardRequest from a POA ServantManager
 405      * @throws org.omg.CORBA.BAD_PARAM if the servant is not the expected type
 406      */
 407     public ServantObject _servant_preinvoke(String operation,
 408                                             Class expectedType) {
 409         return _get_delegate().servant_preinvoke(this, operation,
 410                                                  expectedType);
 411     }
 412 
 413     /**
 414      * Is called by the local stub after it has invoked an operation
 415      * on the local servant that was previously retrieved from a
 416      * call to the method <code>_servant_preinvoke</code>.
 417      * The <code>_servant_postinvoke</code> method must be called
 418      * if the <code>_servant_preinvoke</code>
 419      * method returned a non-null value, even if an exception was thrown
 420      * by the method invoked by the servant. For this reason, the call
 421      * to the method <code>_servant_postinvoke</code> should be placed
 422      * in a Java <code>finally</code> clause.
 423      *
 424      * @param servant the instance of the <code>ServantObject</code>
 425      *        returned by the <code>_servant_preinvoke</code> method
 426      */
 427     public void _servant_postinvoke(ServantObject servant) {
 428         _get_delegate().servant_postinvoke(this, servant);
 429     }
 430 
 431     /*
 432      * The following methods were added by orbos/98-04-03: Java to IDL
 433      * Mapping. These are used by RMI over IIOP.
 434      */
 435 
 436     /**
 437      * Returns an <code>OutputStream</code> object to use for marshalling
 438      * the arguments of the given method.  This method is called by a stub,
 439      * which must indicate if a response is expected, that is, whether or not
 440      * the call is oneway.
 441      *
 442      * @param operation         a String giving the name of the method.
 443      * @param responseExpected  a boolean -- <code>true</code> if the
 444      *         request is not one way, that is, a response is expected
 445      * @return an <code>OutputStream</code> object for dispatching the request
 446      */
 447     public OutputStream _request(String operation,
 448                                  boolean responseExpected) {
 449         return _get_delegate().request(this, operation, responseExpected);
 450     }
 451 
 452     /**
 453      * Invokes an operation and returns an <code>InputStream</code>
 454      * object for reading the response. The stub provides the
 455      * <code>OutputStream</code> object that was previously returned by a
 456      * call to the <code>_request</code> method. The method specified
 457      * as an argument to <code>_request</code> when it was
 458      * called previously is the method that this method invokes.
 459      * <P>
 460      * If an exception occurs, the <code>_invoke</code> method may throw an
 461      * <code>ApplicationException</code> object that contains an InputStream from
 462      * which the user exception state may be unmarshalled.
 463      *
 464      * @param output  an OutputStream object for dispatching the request
 465      * @return an <code>InputStream</code> object containing the marshalled
 466      *         response to the method invoked
 467      * @throws ApplicationException if the invocation
 468      *         meets application-defined exception
 469      * @throws RemarshalException if the invocation leads
 470      *         to a remarshalling error
 471      * @see #_request
 472      */
 473     public InputStream _invoke(OutputStream output)
 474         throws ApplicationException, RemarshalException {
 475         return _get_delegate().invoke(this, output);
 476     }
 477 
 478     /**
 479      * Releases the given
 480      * reply stream back to the ORB when unmarshalling has
 481      * completed after a call to the method <code>_invoke</code>.
 482      * Calling this method is optional for the stub.
 483      *
 484      * @param input  the <code>InputStream</code> object that was returned
 485      *        by the <code>_invoke</code> method or the
 486      *        <code>ApplicationException.getInputStream</code> method;
 487      *        may be <code>null</code>, in which case this method does
 488      *        nothing
 489      * @see #_invoke
 490      */
 491     public void _releaseReply(InputStream input) {
 492         _get_delegate().releaseReply(this, input);
 493     }
 494 
 495     /**
 496      * Returns a <code>String</code> object that represents this
 497      * <code>ObjectImpl</code> object.
 498      *
 499      * @return the <code>String</code> representation of this object
 500      */
 501     public String toString() {
 502         if ( __delegate != null )
 503            return __delegate.toString(this);
 504         else
 505            return getClass().getName() + ": no delegate set";
 506     }
 507 
 508     /**
 509      * Returns the hash code for this <code>ObjectImpl</code> object.
 510      *
 511      * @return the hash code for this object
 512      */
 513     public int hashCode() {
 514         if ( __delegate != null )
 515            return __delegate.hashCode(this);
 516         else
 517             return super.hashCode();
 518     }
 519 
 520     /**
 521      * Compares this <code>ObjectImpl</code> object with the given one
 522      * for equality.
 523      *
 524      *@param obj the object with which to compare this object
 525      *@return <code>true</code> if the two objects are equal;
 526      *        <code>false</code> otherwise
 527      */
 528     public boolean equals(java.lang.Object obj) {
 529         if ( __delegate != null )
 530            return __delegate.equals(this, obj);
 531         else
 532            return (this==obj);
 533     }
 534 }