ObjectImpl.java revision 608:7e06bf1dcb09
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 */
25package org.omg.CORBA.portable;
26
27import org.omg.CORBA.Request;
28import org.omg.CORBA.NamedValue;
29import org.omg.CORBA.NVList;
30import org.omg.CORBA.ExceptionList;
31import org.omg.CORBA.ContextList;
32import org.omg.CORBA.Context;
33import org.omg.CORBA.TypeCode;
34import org.omg.CORBA.BAD_OPERATION;
35import 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
46abstract 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}
535