RequestImpl.java revision 608:7e06bf1dcb09
11592Srgrimes/*
21592Srgrimes * Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved.
31592Srgrimes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
41592Srgrimes *
51592Srgrimes * This code is free software; you can redistribute it and/or modify it
61592Srgrimes * under the terms of the GNU General Public License version 2 only, as
71592Srgrimes * published by the Free Software Foundation.  Oracle designates this
81592Srgrimes * particular file as subject to the "Classpath" exception as provided
91592Srgrimes * by Oracle in the LICENSE file that accompanied this code.
101592Srgrimes *
111592Srgrimes * This code is distributed in the hope that it will be useful, but WITHOUT
12262435Sbrueffer * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
131592Srgrimes * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
141592Srgrimes * version 2 for more details (a copy is included in the LICENSE file that
151592Srgrimes * accompanied this code).
161592Srgrimes *
171592Srgrimes * You should have received a copy of the GNU General Public License version
181592Srgrimes * 2 along with this work; if not, write to the Free Software Foundation,
191592Srgrimes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
201592Srgrimes *
211592Srgrimes * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
221592Srgrimes * or visit www.oracle.com if you need additional information or have any
231592Srgrimes * questions.
241592Srgrimes */
251592Srgrimes/*
261592Srgrimes * Licensed Materials - Property of IBM
271592Srgrimes * RMI-IIOP v1.0
281592Srgrimes * Copyright IBM Corp. 1998 1999  All Rights Reserved
2950476Speter *
301592Srgrimes */
31141588Sru
321592Srgrimespackage com.sun.corba.se.impl.corba;
3379529Sru
341592Srgrimes
351592Srgrimesimport org.omg.CORBA.Any;
361592Srgrimesimport org.omg.CORBA.ARG_IN;
371592Srgrimesimport org.omg.CORBA.ARG_OUT;
3868949Sruimport org.omg.CORBA.ARG_INOUT;
3911486Sdgimport org.omg.CORBA.Context;
401592Srgrimesimport org.omg.CORBA.ContextList;
4199500Scharnierimport org.omg.CORBA.Environment;
4299500Scharnierimport org.omg.CORBA.ExceptionList;
4399500Scharnierimport org.omg.CORBA.NVList;
441592Srgrimesimport org.omg.CORBA.NamedValue;
45131487Sruimport org.omg.CORBA.Request;
46131487Sruimport org.omg.CORBA.SystemException;
471592Srgrimesimport org.omg.CORBA.TCKind;
481592Srgrimesimport org.omg.CORBA.TypeCode;
491592Srgrimesimport org.omg.CORBA.TypeCodePackage.BadKind;
5068949Sruimport org.omg.CORBA.UnknownUserException;
5131405Scharnierimport org.omg.CORBA.Bounds;
5211486Sdgimport org.omg.CORBA.UNKNOWN;
53131487Sruimport org.omg.CORBA.INTERNAL;
54131487Sruimport org.omg.CORBA.NO_IMPLEMENT;
5511486Sdgimport org.omg.CORBA.CompletionStatus;
561592Srgrimesimport org.omg.CORBA.WrongTransaction;
571592Srgrimes
581592Srgrimesimport org.omg.CORBA.portable.ApplicationException ;
591592Srgrimesimport org.omg.CORBA.portable.RemarshalException ;
601592Srgrimesimport org.omg.CORBA.portable.InputStream ;
611592Srgrimesimport org.omg.CORBA.portable.OutputStream ;
621592Srgrimes
631592Srgrimesimport com.sun.corba.se.spi.orb.ORB;
641592Srgrimesimport com.sun.corba.se.spi.presentation.rmi.StubAdapter;
651592Srgrimesimport com.sun.corba.se.spi.logging.CORBALogDomains;
6699500Scharnierimport com.sun.corba.se.impl.logging.ORBUtilSystemException;
6799500Scharnierimport com.sun.corba.se.impl.corba.AsynchInvoke;
6899500Scharnier
6955562Sphantompublic class RequestImpl
7055562Sphantom    extends Request
7155562Sphantom{
721592Srgrimes    ///////////////////////////////////////////////////////////////////////////
731592Srgrimes    // data members
741592Srgrimes
751592Srgrimes    protected org.omg.CORBA.Object _target;
761592Srgrimes    protected String             _opName;
771592Srgrimes    protected NVList             _arguments;
781592Srgrimes    protected ExceptionList      _exceptions;
791592Srgrimes    private NamedValue           _result;
801592Srgrimes    protected Environment        _env;
811592Srgrimes    private Context              _ctx;
821592Srgrimes    private ContextList          _ctxList;
831592Srgrimes    protected ORB                _orb;
841592Srgrimes    private ORBUtilSystemException _wrapper;
851592Srgrimes
861592Srgrimes    // invocation-specific stuff
871592Srgrimes    protected boolean            _isOneWay      = false;
881592Srgrimes    private int[]                _paramCodes;
891592Srgrimes    private long[]               _paramLongs;
901592Srgrimes    private java.lang.Object[]   _paramObjects;
911592Srgrimes
921592Srgrimes    // support for deferred invocations.
931592Srgrimes    // protected instead of private since it needs to be set by the
941592Srgrimes    // thread object doing the asynchronous invocation.
951592Srgrimes    protected boolean            gotResponse    = false;
961592Srgrimes
971592Srgrimes    ///////////////////////////////////////////////////////////////////////////
981592Srgrimes    // constructor
9979754Sdd
10031405Scharnier    // REVISIT - used to be protected.  Now public so it can be
1011592Srgrimes    // accessed from xgiop.
1021592Srgrimes    public RequestImpl (ORB orb,
10379754Sdd                        org.omg.CORBA.Object targetObject,
1041592Srgrimes                        Context ctx,
1051592Srgrimes                        String operationName,
10679754Sdd                        NVList argumentList,
1071592Srgrimes                        NamedValue resultContainer,
1081592Srgrimes                        ExceptionList exceptionList,
1091592Srgrimes                        ContextList ctxList)
1101592Srgrimes    {
1111592Srgrimes
1121592Srgrimes        // initialize the orb
1131592Srgrimes        _orb    = orb;
1141592Srgrimes        _wrapper = ORBUtilSystemException.get( orb,
1151592Srgrimes            CORBALogDomains.OA_INVOCATION ) ;
1161592Srgrimes
1171592Srgrimes        // initialize target, context and operation name
1181592Srgrimes        _target     = targetObject;
1191592Srgrimes        _ctx    = ctx;
1201592Srgrimes        _opName = operationName;
1211592Srgrimes
1221592Srgrimes        // initialize argument list if not passed in
12331405Scharnier        if (argumentList == null)
124131487Sru            _arguments = new NVListImpl(_orb);
125131487Sru        else
1261592Srgrimes            _arguments = argumentList;
1271592Srgrimes
1281592Srgrimes        // set result container.
1291592Srgrimes        _result = resultContainer;
1301592Srgrimes
131131487Sru        // initialize exception list if not passed in
132131487Sru        if (exceptionList == null)
1331592Srgrimes            _exceptions = new ExceptionListImpl();
1341592Srgrimes        else
135108221Sru            _exceptions = exceptionList;
1361592Srgrimes
1371592Srgrimes        // initialize context list if not passed in
1381592Srgrimes        if (ctxList == null)
1391592Srgrimes            _ctxList = new ContextListImpl(_orb);
1401592Srgrimes        else
1411592Srgrimes            _ctxList = ctxList;
1421592Srgrimes
1431592Srgrimes        // initialize environment
1441592Srgrimes        _env    = new EnvironmentImpl();
1451592Srgrimes
146140414Sru    }
147140414Sru
148140414Sru    public org.omg.CORBA.Object target()
149140414Sru    {
150140414Sru        return _target;
151140414Sru    }
152140414Sru
1531592Srgrimes    public String operation()
1541592Srgrimes    {
1551592Srgrimes        return _opName;
1561592Srgrimes    }
1571592Srgrimes
15831405Scharnier    public NVList arguments()
1591592Srgrimes    {
1601592Srgrimes        return _arguments;
1611592Srgrimes    }
1621592Srgrimes
16331405Scharnier    public NamedValue result()
1641592Srgrimes    {
1651592Srgrimes        return _result;
1661592Srgrimes    }
1671592Srgrimes
1681592Srgrimes    public Environment env()
16979366Sru    {
17055562Sphantom        return _env;
17155562Sphantom    }
17213680Swosch
17355562Sphantom    public ExceptionList exceptions()
17468756Sben    {
175140414Sru        return _exceptions;
176140414Sru    }
177140414Sru
178140414Sru    public ContextList contexts()
179140414Sru    {
180140414Sru        return _ctxList;
181140414Sru    }
1821592Srgrimes
1831592Srgrimes    public synchronized Context ctx()
184131487Sru    {
185131487Sru        if (_ctx == null)
18655562Sphantom            _ctx = new ContextImpl(_orb);
18755562Sphantom        return _ctx;
18855562Sphantom    }
1891592Srgrimes
1901592Srgrimes    public synchronized void ctx(Context newCtx)
1911592Srgrimes    {
1921592Srgrimes        _ctx = newCtx;
1931592Srgrimes    }
194
195    public synchronized Any add_in_arg()
196    {
197        return _arguments.add(org.omg.CORBA.ARG_IN.value).value();
198    }
199
200    public synchronized Any add_named_in_arg(String name)
201    {
202        return _arguments.add_item(name, org.omg.CORBA.ARG_IN.value).value();
203    }
204
205    public synchronized Any add_inout_arg()
206    {
207        return _arguments.add(org.omg.CORBA.ARG_INOUT.value).value();
208    }
209
210    public synchronized Any add_named_inout_arg(String name)
211    {
212        return _arguments.add_item(name, org.omg.CORBA.ARG_INOUT.value).value();
213    }
214
215    public synchronized Any add_out_arg()
216    {
217        return _arguments.add(org.omg.CORBA.ARG_OUT.value).value();
218    }
219
220    public synchronized Any add_named_out_arg(String name)
221    {
222        return _arguments.add_item(name, org.omg.CORBA.ARG_OUT.value).value();
223    }
224
225    public synchronized void set_return_type(TypeCode tc)
226    {
227        if (_result == null)
228            _result = new NamedValueImpl(_orb);
229        _result.value().type(tc);
230    }
231
232    public synchronized Any return_value()
233    {
234        if (_result == null)
235            _result = new NamedValueImpl(_orb);
236        return _result.value();
237    }
238
239    public synchronized void add_exception(TypeCode exceptionType)
240    {
241        _exceptions.add(exceptionType);
242    }
243
244    public synchronized void invoke()
245    {
246        doInvocation();
247    }
248
249    public synchronized void send_oneway()
250    {
251        _isOneWay = true;
252        doInvocation();
253    }
254
255    public synchronized void send_deferred()
256    {
257        AsynchInvoke invokeObject = new AsynchInvoke(_orb, this, false);
258        new Thread(invokeObject).start();
259    }
260
261    public synchronized boolean poll_response()
262    {
263        // this method has to be synchronized even though it seems
264        // "readonly" since the thread object doing the asynchronous
265        // invocation can potentially update this variable in parallel.
266        // updates are currently simply synchronized againt the request
267        // object.
268        return gotResponse;
269    }
270
271    public synchronized void get_response()
272        throws org.omg.CORBA.WrongTransaction
273    {
274        while (gotResponse == false) {
275            // release the lock. wait to be notified by the thread that is
276            // doing the asynchronous invocation.
277            try {
278                wait();
279            }
280            catch (InterruptedException e) {}
281        }
282    }
283
284    ///////////////////////////////////////////////////////////////////////////
285    // private helper methods
286
287    /*
288     * The doInvocation operation is where the real mechanics of
289     * performing the request invocation is done.
290     */
291    protected void doInvocation()
292    {
293        org.omg.CORBA.portable.Delegate delegate = StubAdapter.getDelegate(
294            _target ) ;
295
296        // Initiate Client Portable Interceptors.  Inform the PIHandler that
297        // this is a DII request so that it knows to ignore the second
298        // inevitable call to initiateClientPIRequest in createRequest.
299        // Also, save the RequestImpl object for later use.
300        _orb.getPIHandler().initiateClientPIRequest( true );
301        _orb.getPIHandler().setClientPIInfo( this );
302
303        InputStream $in = null;
304        try {
305            OutputStream $out = delegate.request(null, _opName, !_isOneWay);
306            // Marshal args
307            try {
308                for (int i=0; i<_arguments.count() ; i++) {
309                    NamedValue nv = _arguments.item(i);
310                    switch (nv.flags()) {
311                    case ARG_IN.value:
312                        nv.value().write_value($out);
313                        break;
314                    case ARG_OUT.value:
315                        break;
316                    case ARG_INOUT.value:
317                        nv.value().write_value($out);
318                        break;
319                    }
320                }
321            } catch ( org.omg.CORBA.Bounds ex ) {
322                throw _wrapper.boundsErrorInDiiRequest( ex ) ;
323            }
324
325            $in = delegate.invoke(null, $out);
326        } catch (ApplicationException e) {
327            // REVISIT - minor code.
328            // This is already handled in subcontract.
329            // REVISIT - uncomment.
330            //throw new INTERNAL();
331        } catch (RemarshalException e) {
332            doInvocation();
333        } catch( SystemException ex ) {
334            _env.exception(ex);
335            // NOTE: The exception should not be thrown.
336            // However, JDK 1.4 and earlier threw the exception,
337            // so we keep the behavior to be compatible.
338            throw ex;
339        } finally {
340            delegate.releaseReply(null, $in);
341        }
342    }
343
344    // REVISIT -  make protected after development - so xgiop can get it.
345    public void unmarshalReply(InputStream is)
346    {
347        // First unmarshal the return value if it is not void
348        if ( _result != null ) {
349            Any returnAny = _result.value();
350            TypeCode returnType = returnAny.type();
351            if ( returnType.kind().value() != TCKind._tk_void )
352                returnAny.read_value(is, returnType);
353        }
354
355        // Now unmarshal the out/inout args
356        try {
357            for ( int i=0; i<_arguments.count() ; i++) {
358                NamedValue nv = _arguments.item(i);
359                switch( nv.flags() ) {
360                case ARG_IN.value:
361                    break;
362                case ARG_OUT.value:
363                case ARG_INOUT.value:
364                    Any any = nv.value();
365                    any.read_value(is, any.type());
366                    break;
367                }
368            }
369        }
370        catch ( org.omg.CORBA.Bounds ex ) {
371            // Cannot happen since we only iterate till _arguments.count()
372        }
373    }
374}
375