Dynamic_Implementation.cpp

Go to the documentation of this file.
00001 #include "tao/DynamicInterface/Dynamic_Implementation.h"
00002 
00003 ACE_RCSID (DynamicInterface,
00004            Dynamic_Implementation,
00005            "$Id: Dynamic_Implementation.cpp 81140 2008-03-28 09:19:19Z vzykov $")
00006 
00007 
00008 #include "tao/DynamicInterface/Server_Request.h"
00009 #include "tao/ORB_Core.h"
00010 #include "tao/TSS_Resources.h"
00011 #include "tao/IFR_Client_Adapter.h"
00012 #include "tao/PortableServer/Root_POA.h"
00013 #include "tao/PortableServer/POA_Current_Impl.h"
00014 #include "tao/PortableServer/Collocated_Arguments_Converter.h"
00015 #include "tao/operation_details.h"
00016 
00017 #include "ace/Dynamic_Service.h"
00018 #include "ace/OS_NS_string.h"
00019 
00020 
00021 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00022 
00023 CORBA::Boolean
00024 TAO_DynamicImplementation::_is_a (const char *logical_type_id)
00025 {
00026   CORBA::RepositoryId_var id = this->get_id_from_primary_interface ();
00027 
00028   return ACE_OS::strcmp (logical_type_id, id.in ()) == 0;
00029 }
00030 
00031 CORBA::Object_ptr
00032 TAO_DynamicImplementation::_this (void)
00033 {
00034   // The _this() function returns a CORBA::Object_ptr for the target
00035   // object. Unlike _this() for static skeletons, its return type is
00036   // not interface-specific because a DSI servant may very well
00037   // incarnate multiple CORBA objects of different types.
00038   TAO_Stub *stub = this->_create_stub ();
00039 
00040   // Create a object.
00041   CORBA::Object_ptr retval = CORBA::Object_ptr ();
00042   ACE_NEW_RETURN (retval,
00043                   CORBA::Object (stub,
00044                                  1,
00045                                  this),
00046                   CORBA::Object::_nil ());
00047 
00048   return retval;
00049 }
00050 
00051 CORBA::InterfaceDef_ptr
00052 TAO_DynamicImplementation::_get_interface (void)
00053 {
00054   TAO_IFR_Client_Adapter *adapter =
00055     ACE_Dynamic_Service<TAO_IFR_Client_Adapter>::instance (
00056         TAO_ORB_Core::ifr_client_adapter_name ());
00057 
00058   if (adapter == 0)
00059     {
00060       throw ::CORBA::INTF_REPOS ();
00061     }
00062 
00063   CORBA::RepositoryId_var id = this->get_id_from_primary_interface ();
00064 
00065   // This doesn't take multiple ORBs into account, but it's being
00066   // used only to resolve the IFR, so we should be ok.
00067   return adapter->get_interface (TAO_ORB_Core_instance ()->orb (), id.in ());
00068 }
00069 
00070 const char *
00071 TAO_DynamicImplementation::_interface_repository_id (void) const
00072 {
00073   // This should never be called.
00074   return 0;
00075 }
00076 
00077 void *
00078 TAO_DynamicImplementation::_downcast (const char *)
00079 {
00080   // Don't know enough to do better.
00081   return this;
00082 }
00083 
00084 TAO_Stub *
00085 TAO_DynamicImplementation::_create_stub (void)
00086 {
00087   // If DynamicImplementation::_this() is invoked outside of the
00088   // context of a request invocation on a target object being served
00089   // by the DSI servant, it raises the PortableServer::WrongPolicy
00090   // exception. See the CORBA C++ mapping, section 1.38.3.
00091   TAO::Portable_Server::POA_Current_Impl *poa_current_impl =
00092     static_cast <TAO::Portable_Server::POA_Current_Impl *>
00093                      (TAO_TSS_Resources::instance ()->poa_current_impl_);
00094 
00095   if (poa_current_impl == 0
00096       || this != poa_current_impl->servant ())
00097     {
00098       throw PortableServer::POA::WrongPolicy ();
00099     }
00100 
00101   PortableServer::POA_var poa =
00102     poa_current_impl->get_POA ();
00103 
00104   CORBA::PolicyList_var client_exposed_policies =
00105     poa_current_impl->poa ()->client_exposed_policies (
00106         poa_current_impl->priority ());
00107 
00108   CORBA::RepositoryId_var pinterface =
00109     this->_primary_interface (poa_current_impl->object_id (), poa.in ());
00110 
00111   return
00112     poa_current_impl->poa ()->key_to_stub (poa_current_impl->object_key (),
00113                                            pinterface.in (),
00114                                            poa_current_impl->priority ());
00115 }
00116 
00117 void
00118 TAO_DynamicImplementation::_dispatch (TAO_ServerRequest &request,
00119                                       void * /* context */)
00120 {
00121   // No need to do any of this if the client isn't waiting.
00122   if (request.response_expected ())
00123     {
00124       if (request.is_forwarded ())
00125         {
00126           request.init_reply ();
00127           request.tao_send_reply ();
00128 
00129           // No need to invoke in this case.
00130           return;
00131         }
00132       else if (request.sync_with_server ())
00133         {
00134           // The last line before the call to this function
00135           // was an ACE_CHECK_RETURN, so if we're here, we
00136           // know there is no exception so far, and that's all
00137           // a SYNC_WITH_SERVER client request cares about.
00138           request.send_no_exception_reply ();
00139         }
00140     }
00141 
00142   // Create DSI request object.
00143   CORBA::ServerRequest *dsi_request = 0;
00144   ACE_NEW (dsi_request,
00145            CORBA::ServerRequest (request));
00146 
00147   try
00148     {
00149       // Delegate to user.
00150       this->invoke (dsi_request);
00151 
00152       // Only if the client is waiting.
00153       if (request.response_expected () && !request.sync_with_server ())
00154         {
00155           dsi_request->dsi_marshal ();
00156         }
00157     }
00158   catch (::CORBA::Exception& ex)
00159     {
00160       // Only if the client is waiting.
00161       if (request.response_expected () && !request.sync_with_server ())
00162         {
00163           if (request.collocated ()
00164                && request.operation_details ()->cac () != 0)
00165             {
00166               // If we have a cac it will handle the exception and no
00167               // need to do any further processing
00168               request.operation_details ()->cac ()->handle_corba_exception (
00169                 request, &ex);
00170               return;
00171             }
00172           else
00173             request.tao_send_reply_exception (ex);
00174         }
00175     }
00176 
00177   ::CORBA::release (dsi_request);
00178 }
00179 
00180 CORBA::RepositoryId
00181 TAO_DynamicImplementation::get_id_from_primary_interface (void)
00182 {
00183   // If this method is called outside of the
00184   // context of a request invocation on a target object being served
00185   // by the DSI servant, it raises the PortableServer::WrongPolicy
00186   // exception. See the CORBA C++ mapping, section 1.38.3.
00187   TAO::Portable_Server::POA_Current_Impl *poa_current_impl =
00188     static_cast <TAO::Portable_Server::POA_Current_Impl *>
00189                      (TAO_TSS_Resources::instance ()->poa_current_impl_);
00190 
00191   if (poa_current_impl == 0
00192       || this != poa_current_impl->servant ())
00193     {
00194       throw PortableServer::POA::WrongPolicy ();
00195     }
00196 
00197   PortableServer::POA_var poa = poa_current_impl->get_POA ();
00198 
00199   return this->_primary_interface (poa_current_impl->object_id (), poa.in ());
00200 }
00201 
00202 TAO_END_VERSIONED_NAMESPACE_DECL

Generated on Tue Feb 2 17:43:23 2010 for TAO_DynamicInterface by  doxygen 1.4.7