OperationInterfaceI.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002   tag: The SourceWorks  Tue Sep 7 00:55:18 CEST 2010  OperationInterfaceI.cpp
00003 
00004                         OperationInterfaceI.cpp -  description
00005                            -------------------
00006     begin                : Tue September 07 2010
00007     copyright            : (C) 2010 The SourceWorks
00008     email                : peter@thesourceworks.com
00009 
00010  ***************************************************************************
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU General Public                   *
00013  *   License as published by the Free Software Foundation;                 *
00014  *   version 2 of the License.                                             *
00015  *                                                                         *
00016  *   As a special exception, you may use this file as part of a free       *
00017  *   software library without restriction.  Specifically, if other files   *
00018  *   instantiate templates or use macros or inline functions from this     *
00019  *   file, or you compile this file and link it with other files to        *
00020  *   produce an executable, this file does not by itself cause the         *
00021  *   resulting executable to be covered by the GNU General Public          *
00022  *   License.  This exception does not however invalidate any other        *
00023  *   reasons why the executable file might be covered by the GNU General   *
00024  *   Public License.                                                       *
00025  *                                                                         *
00026  *   This library is distributed in the hope that it will be useful,       *
00027  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00028  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00029  *   Lesser General Public License for more details.                       *
00030  *                                                                         *
00031  *   You should have received a copy of the GNU General Public             *
00032  *   License along with this library; if not, write to the Free Software   *
00033  *   Foundation, Inc., 59 Temple Place,                                    *
00034  *   Suite 330, Boston, MA  02111-1307  USA                                *
00035  *                                                                         *
00036  ***************************************************************************/
00037 
00038 
00039 // -*- C++ -*-
00040 //
00041 // $Id$
00042 
00043 // ****  Code generated by the The ACE ORB (TAO) IDL Compiler ****
00044 // TAO and the TAO IDL Compiler have been developed by:
00045 //       Center for Distributed Object Computing
00046 //       Washington University
00047 //       St. Louis, MO
00048 //       USA
00049 //       http://www.cs.wustl.edu/~schmidt/doc-center.html
00050 // and
00051 //       Distributed Object Computing Laboratory
00052 //       University of California at Irvine
00053 //       Irvine, CA
00054 //       USA
00055 //       http://doc.ece.uci.edu/
00056 // and
00057 //       Institute for Software Integrated Systems
00058 //       Vanderbilt University
00059 //       Nashville, TN
00060 //       USA
00061 //       http://www.isis.vanderbilt.edu/
00062 //
00063 // Information about TAO is available at:
00064 //     http://www.cs.wustl.edu/~schmidt/TAO.html
00065 
00066 // TAO_IDL - Generated from
00067 // ../../../ACE_wrappers/TAO/TAO_IDL/be/be_codegen.cpp:1196
00068 
00069 #include "CorbaLib.hpp"
00070 #include "CorbaTypeTransporter.hpp"
00071 #include "OperationInterfaceI.h"
00072 #include "AnyDataSource.hpp"
00073 #include "../../rtt-detail-fwd.hpp"
00074 #include "../../internal/OperationCallerC.hpp"
00075 #include "../../internal/SendHandleC.hpp"
00076 #include "../../Logger.hpp"
00077 #include "../../internal/GlobalEngine.hpp"
00078 
00079 using namespace RTT;
00080 using namespace RTT::detail;
00081 using namespace std;
00082 
00083 RTT_corba_CSendHandle_i::RTT_corba_CSendHandle_i (SendHandleC const& sh, OperationInterfacePart* ofp)
00084 : mhandle(sh), morig(sh), mofp(ofp)
00085 {
00086     // this will always be correct:
00087     for (unsigned int i = 1; i <= mofp->collectArity(); ++i) {
00088         const TypeInfo* ti = mofp->getCollectType(i); // retrieve 1..collectArity()
00089         assert(ti);
00090         cargs.push_back( ti->buildValue() );
00091         mhandle.arg( cargs.back() );
00092     }
00093     assert( mhandle.ready() );
00094 }
00095 
00096 RTT_corba_CSendHandle_i::~RTT_corba_CSendHandle_i (void)
00097 {
00098 }
00099 
00106 bool anysequence_to_sourcevector( CAnyArguments const& anys, vector<DataSourceBase::shared_ptr>& sources) {
00107     return false;
00108 }
00109 
00116 bool sourcevector_to_anysequence( vector<DataSourceBase::shared_ptr> const& sources, CAnyArguments & anys ) {
00117     bool valid = true;
00118     anys.length( sources.size() );
00119     for(unsigned int i = 0; i != sources.size(); ++i) {
00120         const TypeInfo* ti = sources[i]->getTypeInfo();
00121         CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) );
00122         ctt->updateAny(sources[i], anys[i]);
00123     }
00124     return valid;
00125 }
00126 
00127 ::RTT::corba::CSendStatus RTT_corba_CSendHandle_i::collect (
00128     ::RTT::corba::CAnyArguments_out args)
00129 {
00130     try {
00131         SendStatus ss = mhandle.collect();
00132         args = new CAnyArguments();
00133         if (ss == SendSuccess) {
00134            sourcevector_to_anysequence( cargs, *args.ptr() );
00135         }
00136         return CSendStatus(static_cast<int>(ss) + 2);
00137     } catch(std::runtime_error& e) {
00138         throw ::RTT::corba::CCallError(e.what());
00139     }
00140 }
00141 
00142 ::RTT::corba::CSendStatus RTT_corba_CSendHandle_i::collectIfDone (
00143     ::RTT::corba::CAnyArguments_out args)
00144 {
00145     try {
00146         SendStatus ss = mhandle.collectIfDone();
00147         args = new CAnyArguments();
00148         if (ss == SendSuccess) {
00149             sourcevector_to_anysequence( cargs, *args.ptr() );
00150         }
00151         return CSendStatus(static_cast<int>(ss) + 2);
00152     } catch(std::runtime_error& e) {
00153         throw ::RTT::corba::CCallError(e.what());
00154     }
00155 }
00156 
00157 ::RTT::corba::CSendStatus RTT_corba_CSendHandle_i::checkStatus (
00158     void)
00159 {
00160     return CSendStatus( static_cast<int>(mhandle.collectIfDone()) + 2 );
00161 }
00162 
00163 ::CORBA::Any * RTT_corba_CSendHandle_i::ret (
00164     void)
00165 {
00166     try {
00167         SendStatus ss = mhandle.collectIfDone();
00168         // We just copy over the first collectable argument. In
00169         // case of a void operation, we will thus return the first
00170         // reference argument.
00171         if (ss == SendSuccess) {
00172             if ( cargs.size() > 0) {
00173                 CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> (cargs[0]->getTypeInfo()->getProtocol(ORO_CORBA_PROTOCOL_ID));
00174                 return ctt->createAny( cargs[0] );
00175             }
00176         }
00177         return new CORBA::Any();
00178     } catch(std::runtime_error& e) {
00179         throw ::RTT::corba::CCallError(e.what());
00180     }
00181 }
00182 
00183 void RTT_corba_CSendHandle_i::checkArguments (
00184     const ::RTT::corba::CAnyArguments & args)
00185 {
00186     try {
00187         SendHandleC shc(morig);
00188         for (unsigned int i = 0; i != mofp->collectArity(); ++i) {
00189             const TypeInfo* ti = mofp->getCollectType(i + 1);
00190             assert(ti);
00191             CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> (ti->getProtocol(ORO_CORBA_PROTOCOL_ID));
00192             shc.arg(ctt->createDataSource(&args[i]));
00193         }
00194         // otherwise, we would block !!!
00195         shc.setAutoCollect(false);
00196         shc.check();
00197     } catch (name_not_found_exception& nnf) {
00198         throw ::RTT::corba::CNoSuchNameException(nnf.name.c_str());
00199     } catch (wrong_number_of_args_exception& wna) {
00200         throw ::RTT::corba::CWrongNumbArgException(wna.wanted, wna.received);
00201     } catch (wrong_types_of_args_exception& wta) {
00202         throw ::RTT::corba::CWrongTypeArgException(wta.whicharg, wta.expected_.c_str(), wta.received_.c_str());
00203     }
00204 }
00205 
00206 void RTT_corba_CSendHandle_i::dispose (
00207     void)
00208 {
00209     PortableServer::POA_var mPOA = _default_POA();
00210     PortableServer::ObjectId_var oid = mPOA->servant_to_id(this);
00211     mPOA->deactivate_object( oid.in() );
00212     return;
00213 }
00214 
00215 // Implementation skeleton constructor
00216 RTT_corba_COperationInterface_i::RTT_corba_COperationInterface_i (OperationInterface* gmf, PortableServer::POA_ptr the_poa)
00217     :mfact(gmf), mpoa( PortableServer::POA::_duplicate(the_poa))
00218 {
00219 }
00220 
00221 PortableServer::POA_ptr RTT_corba_COperationInterface_i::_default_POA()
00222 {
00223     return PortableServer::POA::_duplicate(mpoa);
00224 }
00225 
00226 
00227 // Implementation skeleton destructor
00228 RTT_corba_COperationInterface_i::~RTT_corba_COperationInterface_i (void)
00229 {
00230 }
00231 
00232 ::RTT::corba::COperationInterface::COperationList * RTT_corba_COperationInterface_i::getOperations (
00233     void)
00234 {
00235     RTT::corba::COperationInterface::COperationList_var rlist = new RTT::corba::COperationInterface::COperationList();
00236 
00237     vector<string> flist = mfact->getNames();
00238     rlist->length( flist.size() );
00239     size_t drops=0;
00240     for (size_t i=0; i != flist.size(); ++i)
00241         if ( !mfact->isSynchronous(flist[i]) ) {
00242             rlist[i - drops] = CORBA::string_dup( flist[i].c_str() );
00243         } else {
00244             ++drops;
00245         }
00246     rlist->length( flist.size() - drops); // we don't show the synchronous operations.
00247     return rlist._retn();
00248 }
00249 
00250 ::RTT::corba::CDescriptions * RTT_corba_COperationInterface_i::getArguments (
00251     const char * operation)
00252 {
00253     CDescriptions_var ret = new CDescriptions();
00254     if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)))
00255         throw ::RTT::corba::CNoSuchNameException( operation );
00256     // operation found, convert args:
00257     OperationInterface::Descriptions args = mfact->getArgumentList( string(operation) );
00258     ret->length( args.size() );
00259     for (size_t i =0; i != args.size(); ++i) {
00260         ret[i].name = CORBA::string_dup( args[i].name.c_str() );
00261         ret[i].description = CORBA::string_dup( args[i].description.c_str() );
00262         ret[i].type = CORBA::string_dup( args[i].type.c_str() );
00263     }
00264     return ret._retn();
00265 }
00266 
00267 char * RTT_corba_COperationInterface_i::getResultType (
00268     const char * operation)
00269 {
00270     if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
00271         throw ::RTT::corba::CNoSuchNameException( operation );
00272     return CORBA::string_dup( mfact->getResultType( string(operation) ).c_str() );
00273 }
00274 
00275 char* RTT_corba_COperationInterface_i::getArgumentType(
00276         const char* operation,
00277         CORBA::UShort nbr)
00278 {
00279     if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
00280         throw ::RTT::corba::CNoSuchNameException( operation );
00281     if ( nbr > mfact->getPart(operation)->arity() )
00282         throw ::RTT::corba::CWrongArgumentException( nbr, mfact->getPart(operation)->arity() );
00283     return CORBA::string_dup( mfact->getPart( operation )->getArgumentType(nbr)->getTypeName().c_str() );
00284 }
00285 
00286 char* RTT_corba_COperationInterface_i::getCollectType(
00287         const char* operation,
00288         CORBA::UShort nbr)
00289 {
00290     if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
00291         throw ::RTT::corba::CNoSuchNameException( operation );
00292     if ( nbr > mfact->getPart(operation)->collectArity() )
00293         throw ::RTT::corba::CWrongArgumentException( nbr, mfact->getPart(operation)->collectArity() );
00294     return CORBA::string_dup( mfact->getPart( operation )->getCollectType(nbr)->getTypeName().c_str() );
00295 
00296 }
00297 
00298 ::CORBA::UShort RTT_corba_COperationInterface_i::getArity (
00299     const char * operation)
00300 {
00301     if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
00302         throw ::RTT::corba::CNoSuchNameException( operation );
00303     return mfact->getPart(operation)->arity();
00304 }
00305 
00306 ::CORBA::UShort RTT_corba_COperationInterface_i::getCollectArity (
00307     const char * operation)
00308 {
00309     if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
00310         throw ::RTT::corba::CNoSuchNameException( operation );
00311     return mfact->getPart(operation)->collectArity();
00312 }
00313 
00314 char * RTT_corba_COperationInterface_i::getDescription (
00315     const char * operation)
00316 {
00317     if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
00318         throw ::RTT::corba::CNoSuchNameException( operation );
00319     return CORBA::string_dup( mfact->getDescription( string(operation) ).c_str() );
00320 }
00321 
00322 void RTT_corba_COperationInterface_i::checkOperation (
00323     const char * operation,
00324     const ::RTT::corba::CAnyArguments & args)
00325 {
00326     if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
00327         throw ::RTT::corba::CNoSuchNameException( operation );
00328     try {
00329         OperationInterfacePart* mofp = mfact->getPart(operation);
00330         OperationCallerC mc(mofp, operation, internal::GlobalEngine::Instance());
00331         for (unsigned int i = 0; i < mofp->arity() && i < args.length(); ++i) {
00332             const TypeInfo* ti = mofp->getArgumentType(i+1);
00333             assert(ti);
00334             CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> (ti->getProtocol(ORO_CORBA_PROTOCOL_ID));
00335             if (ctt) {
00336                 DataSourceBase::shared_ptr ds = ctt->createDataSource(&args[i]);
00337                 if (ds)
00338                         mc.arg(ds);
00339                 else {
00340                         log(Error) << "Registered transport for type "<< ti->getTypeName()
00341                                         << " could not create data source from Any (argument "<< i+1
00342                                         <<"): calling operation '"<< operation <<"' will fail." <<endlog();
00343                 }
00344             } else {
00345                 throw wrong_types_of_args_exception(i+1,"type known to CORBA", ti->getTypeName());
00346             }
00347         }
00348         mc.check();
00349     } catch (no_asynchronous_operation_exception& ) {
00350         throw ::RTT::corba::CNoSuchNameException(operation);
00351     } catch (name_not_found_exception& nnf) {
00352         throw ::RTT::corba::CNoSuchNameException(nnf.name.c_str());
00353     } catch (wrong_number_of_args_exception& wna) {
00354         throw ::RTT::corba::CWrongNumbArgException(wna.wanted, wna.received);
00355     } catch (wrong_types_of_args_exception& wta) {
00356         throw ::RTT::corba::CWrongTypeArgException(wta.whicharg, wta.expected_.c_str(), wta.received_.c_str());
00357     }
00358 }
00359 
00360 ::CORBA::Any * RTT_corba_COperationInterface_i::callOperation (
00361     const char * operation,
00362     ::RTT::corba::CAnyArguments & args)
00363 {
00364     if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
00365         throw ::RTT::corba::CNoSuchNameException( operation );
00366     // convert Corba args to C++ args.
00367     try {
00368         OperationCallerC orig(mfact->getPart(operation), operation, internal::GlobalEngine::Instance());
00369         vector<DataSourceBase::shared_ptr> results;
00370         for (size_t i =0; i != args.length(); ++i) {
00371             const TypeInfo* ti = mfact->getPart(operation)->getArgumentType( i + 1);
00372             CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) );
00373             // we need to store the results for returning them to caller (args is inout!) after the call()
00374             results.push_back( ctt->createDataSource( &args[i] ) );
00375             orig.arg( results[i] );
00376         }
00377         if ( orig.ready() ) {
00378             DataSourceBase::shared_ptr ds = orig.getCallDataSource();
00379             CORBA::Any* retany;
00380 
00381             // Try to get the return result :
00382             const TypeInfo* ti = ds->getTypeInfo();
00383             CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) );
00384             if ( !ctt ) {
00385                 log(Warning) << "Could not return results of call to " << operation << ": unknown return type by CORBA transport."<<endlog();
00386                 ds->evaluate(); // equivalent to orig.call()
00387                 retany = new CORBA::Any();
00388             } else {
00389                 retany =  ctt->createAny( ds ); // call evaluate internally
00390             }
00391 
00392             // Return results into args:
00393             for (size_t i =0; i != args.length(); ++i) {
00394                 const TypeInfo* ti = mfact->getPart(operation)->getArgumentType( i + 1);
00395                 CorbaTypeTransporter* ctta = dynamic_cast<CorbaTypeTransporter*> ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) );
00396                 ctta->updateAny(results[i], args[i]);
00397             }
00398             return retany;
00399         } else {
00400             orig.check(); // will throw
00401         }
00402     } catch (no_asynchronous_operation_exception& ) {
00403         throw ::RTT::corba::CNoSuchNameException( operation );
00404     } catch ( name_not_found_exception& ) {
00405         throw ::RTT::corba::CNoSuchNameException( operation );
00406     } catch ( wrong_number_of_args_exception& wna ) {
00407         throw ::RTT::corba::CWrongNumbArgException( wna.wanted, wna.received );
00408     } catch (wrong_types_of_args_exception& wta ) {
00409         throw ::RTT::corba::CWrongTypeArgException( wta.whicharg, wta.expected_.c_str(), wta.received_.c_str() );
00410     } catch (std::runtime_error& e){
00411         throw ::RTT::corba::CCallError(e.what());
00412     }
00413     return new ::CORBA::Any();
00414 }
00415 
00416 ::RTT::corba::CSendHandle_ptr RTT_corba_COperationInterface_i::sendOperation (
00417     const char * operation,
00418     const ::RTT::corba::CAnyArguments & args)
00419 {
00420     // This implementation is 90% identical to callOperation above, only deviating in the orig.ready() part.
00421     if ( mfact->hasMember( string( operation ) ) == false || mfact->isSynchronous(string(operation)) )
00422         throw ::RTT::corba::CNoSuchNameException( operation );
00423     // convert Corba args to C++ args.
00424     try {
00425         OperationCallerC orig(mfact->getPart(operation), operation, internal::GlobalEngine::Instance());
00426         for (size_t i =0; i != args.length(); ++i) {
00427             const TypeInfo* ti = mfact->getPart(operation)->getArgumentType( i + 1);
00428             CorbaTypeTransporter* ctt = dynamic_cast<CorbaTypeTransporter*> ( ti->getProtocol(ORO_CORBA_PROTOCOL_ID) );
00429             orig.arg( ctt->createDataSource( &args[i] ));
00430         }
00431         if ( orig.ready() ) {
00432             SendHandleC resulthandle = orig.send();
00433             // we may not destroy the SendHandle, before the operation completes:
00434             resulthandle.setAutoCollect(true);
00435             // our resulthandle copy makes sure that the resulthandle can return.
00436             RTT_corba_CSendHandle_i* ret_i = new RTT_corba_CSendHandle_i( resulthandle, mfact->getPart(operation) );
00437             CSendHandle_var ret = ret_i->_this();
00438             ret_i->_remove_ref(); // if POA drops this, it gets cleaned up.
00439             return ret._retn();
00440         } else {
00441             orig.check(); // will throw
00442         }
00443     } catch (no_asynchronous_operation_exception& ) {
00444         throw ::RTT::corba::CNoSuchNameException( operation );
00445     } catch ( name_not_found_exception& ) {
00446         throw ::RTT::corba::CNoSuchNameException( operation );
00447     } catch ( wrong_number_of_args_exception& wna ) {
00448         throw ::RTT::corba::CWrongNumbArgException( wna.wanted, wna.received );
00449     } catch (wrong_types_of_args_exception& wta ) {
00450         throw ::RTT::corba::CWrongTypeArgException( wta.whicharg, wta.expected_.c_str(), wta.received_.c_str() );
00451     }
00452     return CSendHandle::_nil();
00453 }


rtt
Author(s): RTT Developers
autogenerated on Fri Sep 9 2016 04:01:55