CorbaPort.hpp

00001 /***************************************************************************
00002   tag: FMTC  do nov 2 13:06:19 CET 2006  CorbaPort.hpp
00003 
00004                         CorbaPort.hpp -  description
00005                            -------------------
00006     begin                : do november 02 2006
00007     copyright            : (C) 2006 FMTC
00008     email                : peter.soetens@fmtc.be
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 
00040 #ifndef ORO_CORBA_PORT_HPP
00041 #define ORO_CORBA_PORT_HPP
00042 
00043 #include <string>
00044 #include "../PortInterface.hpp"
00045 #include "DataFlowC.h"
00046 #include "corba.h"
00047 #include "corba.h"
00048 #ifdef CORBA_IS_TAO
00049 #include <tao/PortableServer/PortableServer.h>
00050 #endif
00051 #include "CorbaConnection.hpp"
00052 #include "CorbaLib.hpp"
00053 
00054 namespace RTT
00055 { namespace Corba {
00056 
00061     class RTT_CORBA_API CorbaPort
00062         : public PortInterface
00063     {
00064     protected:
00065         friend class ConnectionInterface;
00066         AssignableExpression_var mdatachannel;
00067         BufferChannel_var mbufchannel;
00068         DataFlowInterface_var mdflow;
00069         mutable RTT::ConnectionInterface::shared_ptr dc;
00070         bool connect(RTT::ConnectionInterface::shared_ptr conn)
00071         {
00072             if ( dc || !conn )
00073                 return false;
00074             // create a server and connect the remote port to this server.
00075             // ALWAYS check getBuffer() first because getDataSource() always returns a data source.
00076             if ( conn->getBuffer() ) {
00077                 // OK: we have a buffered connection.
00078                 if (mdflow->getConnectionModel(this->getName().c_str()) != DataFlowInterface::Buffered)
00079                     return false;
00080                 detail::TypeTransporter* tt = getTypeInfo()->getProtocol(ORO_CORBA_PROTOCOL_ID);
00081                 if (tt) {
00082                     BufferChannel_var bc = (BufferChannel_ptr)tt->bufferServer( conn->getBuffer(), 0);
00083                     if (mdflow->connectBufferPort(this->getName().c_str(), bc.in() ) ) {
00084                         dc=conn;
00085                         return true;
00086                     }
00087                 }
00088                 return false;
00089             }
00090             if ( conn->getDataSource() ) {
00091                 if (mdflow->getConnectionModel(this->getName().c_str()) != DataFlowInterface::Data)
00092                     return false;
00093                 detail::TypeTransporter* tt = getTypeInfo()->getProtocol(ORO_CORBA_PROTOCOL_ID);
00094                 if (tt) {
00095                     Expression_var expr = (Expression_ptr)tt->dataServer(conn->getDataSource(), 0);
00096                     AssignableExpression_var ae = AssignableExpression::_narrow( expr.in() );
00097                     if ( CORBA::is_nil(expr.in()) || CORBA::is_nil(ae.in()) ) {
00098                         log(Error) << "Could not create server from "<<this->getName() <<endlog();
00099                         return false;
00100                     }
00101                     if (mdflow->connectDataPort(this->getName().c_str(), ae.in() ) ) {
00102                         dc=conn;
00103                         return true;
00104                     }
00105                 }
00106                 return false;
00107             }
00108             return false;
00109         }
00110 
00111     public:
00112         CorbaPort(const std::string& name, DataFlowInterface_ptr dflow, PortableServer::POA_ptr )
00113             : PortInterface(name),
00114               mdatachannel(0), mbufchannel(0),
00115               mdflow( DataFlowInterface::_duplicate(dflow) )
00116         {
00117         }
00118 
00119         CorbaPort(const std::string& name, DataFlowInterface_ptr dflow, AssignableExpression_ptr datachannel, PortableServer::POA_ptr )
00120             : PortInterface(name),
00121               mdatachannel(AssignableExpression::_duplicate(datachannel)), mbufchannel(0),
00122               mdflow( DataFlowInterface::_duplicate(dflow) )
00123         {
00124         }
00125 
00126         CorbaPort(const std::string& name, DataFlowInterface_ptr dflow, BufferChannel_ptr bufchannel, PortableServer::POA_ptr )
00127             : PortInterface(name),
00128               mdatachannel(0), mbufchannel( BufferChannel::_duplicate(bufchannel)),
00129               mdflow( DataFlowInterface::_duplicate(dflow) )
00130         {
00131         }
00132 
00133         ~CorbaPort()
00134         {
00135             if ( dc )
00136                 dc->removePort(this);
00137         }
00138 
00139         AssignableExpression_ptr getDataChannel()
00140         {
00141             if ( !CORBA::is_nil(mdatachannel) )
00142                 return AssignableExpression::_duplicate(mdatachannel);
00143             return mdflow->createDataChannel( this->getName().c_str() );
00144         }
00145 
00146         BufferChannel_ptr getBufferChannel()
00147         {
00148             if ( !CORBA::is_nil(mbufchannel) )
00149                 return BufferChannel::_duplicate(mbufchannel);
00150             return mdflow->createBufferChannel( this->getName().c_str() );
00151         }
00152 
00153         virtual ConnectionModel getConnectionModel() const {
00154             return ConnectionModel(int(mdflow->getConnectionModel( this->getName().c_str() )));
00155         }
00156 
00160         virtual PortType getPortType() const {
00161             return PortType(int(mdflow->getPortType( this->getName().c_str() )));
00162         }
00163 
00164         virtual const TypeInfo* getTypeInfo() const {
00165             TypeInfo* ret = TypeInfoRepository::Instance()->type( mdflow->getDataType(this->getName().c_str()) ) ;
00166             if (ret) return ret;
00167             return detail::DataSourceTypeInfo<detail::UnknownType>::getTypeInfo();
00168         }
00169 
00170         virtual bool connected() const {
00171             return mdflow->isConnected( this->getName().c_str() );
00172         }
00173 
00174         virtual RTT::ConnectionInterface::shared_ptr connection() const {
00175             // return a connection object if remote side is connected.
00176             if ( !dc && this->connected() )
00177                 dc = new CorbaConnection(this->getName(), mdflow.in(), 0 );
00178             return dc;
00179         }
00180 
00181         using PortInterface::connectTo;
00182 
00183         virtual bool connectTo( RTT::ConnectionInterface::shared_ptr conn ) {
00184             // Since a connection is given, an existing impl exists.
00185             if (this->getConnectionModel() == Buffered ) {
00186                 BufferBase::shared_ptr impl = conn->getBuffer();
00187                 if (!impl)
00188                     return false;
00189                 detail::TypeTransporter* tt = conn->getTypeInfo()->getProtocol( ORO_CORBA_PROTOCOL_ID );
00190                 if (tt) {
00191                     //let remote side create to local server.
00192                     Corba::BufferChannel_var bufs = (Corba::BufferChannel_ptr) tt->bufferServer(impl, 0);
00193                     mdflow->connectBufferPort( this->getName().c_str(), bufs.in() );
00194                     dc = conn;
00195                     return true;
00196                 }
00197             }
00198             if (this->getConnectionModel() == Data ) {
00199                 DataSourceBase::shared_ptr impl = conn->getDataSource();
00200                 if (!impl)
00201                     return false;
00202                 detail::TypeTransporter* tt = conn->getTypeInfo()->getProtocol( ORO_CORBA_PROTOCOL_ID );
00203                 if (tt) {
00204                     //let remote side create to local server.
00205                     Corba::Expression_var expr = (Corba::Expression_ptr) tt->dataServer( impl, 0 );
00206                     Corba::AssignableExpression_var as_expr = Corba::AssignableExpression::_narrow( expr.in() );
00207                     mdflow->connectDataPort( this->getName().c_str(), as_expr.in() );
00208                     dc = conn;
00209                     return true;
00210                 }
00211             }
00212             return false;
00213         }
00214 
00215         virtual void disconnect() {
00216             // disconnect the remote port
00217             mdflow->disconnect( this->getName().c_str() );
00218             dc = 0;
00219         }
00220 
00221         virtual PortInterface* clone() const {
00222             return new CorbaPort( this->getName(), mdflow.in(), 0 );
00223         }
00224 
00225         virtual PortInterface* antiClone() const {
00226             return new CorbaPort( this->getName(), mdflow.in(), 0 );
00227         }
00228 
00232         virtual RTT::ConnectionInterface::shared_ptr createConnection(ConnectionTypes::ConnectionType con_type = ConnectionTypes::lockfree)
00233         {
00234             Logger::In in("CorbaPort");
00235             // create a connection one can write to.
00236             if ( this->getPortType() != ReadPort ) {
00237                 RTT::ConnectionInterface::shared_ptr ci = new CorbaConnection( this->getName(), mdflow.in(), 0 );
00238                 ci->addPort(this);
00239                 return ci;
00240             }
00241             // read ports do not create writable connections.
00242             return 0;
00243         }
00244 
00245         virtual RTT::ConnectionInterface::shared_ptr createConnection( BufferBase::shared_ptr buf )
00246         {
00247             RTT::ConnectionInterface::shared_ptr ci;
00248             if (mdflow->getConnectionModel(this->getName().c_str()) != DataFlowInterface::Buffered)
00249                 return ci;
00250             detail::TypeTransporter* tt = getTypeInfo()->getProtocol(ORO_CORBA_PROTOCOL_ID);
00251             if (tt) {
00252                 BufferChannel_var bc = (BufferChannel_ptr)tt->bufferServer(buf, 0);
00253                 if (! CORBA::is_nil(bc) ) {
00254                     ci = new CorbaConnection( this->getName(), mdflow.in(), bc.in(), 0 );
00255                     ci->addPort(this);
00256                 } // else: leave ci empty.
00257             }
00258             return ci;
00259         }
00260 
00261         virtual RTT::ConnectionInterface::shared_ptr createConnection( DataSourceBase::shared_ptr data )
00262         {
00263             RTT::ConnectionInterface::shared_ptr ci;
00264             if (mdflow->getConnectionModel(this->getName().c_str()) != DataFlowInterface::Data)
00265                 return ci;
00266             detail::TypeTransporter* tt = getTypeInfo()->getProtocol(ORO_CORBA_PROTOCOL_ID);
00267             if (tt) {
00268                 Expression_var ex = (Expression_ptr)tt->dataServer(data, 0);
00269                 AssignableExpression_var ae = AssignableExpression::_narrow( ex.in() );
00270                 if ( !CORBA::is_nil(ae.in()) ) {
00271                     ci = new CorbaConnection( this->getName(), mdflow.in(), ae.in(), 0 );
00272                     ci->addPort(this);
00273                 } // else: leave ci empty.
00274             }
00275             return ci;
00276         }
00277 
00278         virtual int serverProtocol() const {
00279             return ORO_CORBA_PROTOCOL_ID;
00280         }
00281     };
00282 
00283 }}
00284 
00285 #endif
Generated on Thu Dec 23 13:22:36 2010 for Orocos Real-Time Toolkit by  doxygen 1.6.3