summaryrefslogtreecommitdiff
path: root/TAO/tao/DynamicInterface/Dynamic_Implementation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/tao/DynamicInterface/Dynamic_Implementation.cpp')
-rw-r--r--TAO/tao/DynamicInterface/Dynamic_Implementation.cpp221
1 files changed, 221 insertions, 0 deletions
diff --git a/TAO/tao/DynamicInterface/Dynamic_Implementation.cpp b/TAO/tao/DynamicInterface/Dynamic_Implementation.cpp
new file mode 100644
index 00000000000..6e09d9ff5fa
--- /dev/null
+++ b/TAO/tao/DynamicInterface/Dynamic_Implementation.cpp
@@ -0,0 +1,221 @@
+#include "tao/DynamicInterface/Dynamic_Implementation.h"
+
+ACE_RCSID (DynamicInterface,
+ Dynamic_Implementation,
+ "$Id$")
+
+
+#include "tao/DynamicInterface/Server_Request.h"
+#include "tao/ORB_Core.h"
+#include "tao/TSS_Resources.h"
+#include "tao/IFR_Client_Adapter.h"
+#include "tao/PortableServer/Root_POA.h"
+#include "tao/PortableServer/POA_Current_Impl.h"
+
+#include "ace/Dynamic_Service.h"
+#include "ace/OS_NS_string.h"
+
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+CORBA::Boolean
+TAO_DynamicImplementation::_is_a (const char *logical_type_id
+ ACE_ENV_ARG_DECL)
+{
+ CORBA::RepositoryId_var id =
+ this->get_id_from_primary_interface (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (0);
+
+ return ACE_OS::strcmp (logical_type_id, id.in ()) == 0;
+}
+
+CORBA::Object_ptr
+TAO_DynamicImplementation::_this (ACE_ENV_SINGLE_ARG_DECL)
+{
+ // The _this() function returns a CORBA::Object_ptr for the target
+ // object. Unlike _this() for static skeletons, its return type is
+ // not interface-specific because a DSI servant may very well
+ // incarnate multiple CORBA objects of different types.
+ TAO_Stub *stub = this->_create_stub (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (CORBA::Object::_nil ());
+
+ // Create a object.
+ CORBA::Object_ptr retval = CORBA::Object::_nil ();
+ ACE_NEW_RETURN (retval,
+ CORBA::Object (stub,
+ 1,
+ this),
+ CORBA::Object::_nil ());
+
+ return retval;
+}
+
+CORBA::InterfaceDef_ptr
+TAO_DynamicImplementation::_get_interface (ACE_ENV_SINGLE_ARG_DECL)
+{
+ TAO_IFR_Client_Adapter *adapter =
+ ACE_Dynamic_Service<TAO_IFR_Client_Adapter>::instance (
+ TAO_ORB_Core::ifr_client_adapter_name ()
+ );
+
+ if (adapter == 0)
+ {
+ ACE_THROW_RETURN (CORBA::INTF_REPOS (),
+ 0);
+ }
+
+ CORBA::RepositoryId_var id =
+ this->get_id_from_primary_interface (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_CHECK_RETURN (0);
+
+ // This doesn't take multiple ORBs into account, but it's being
+ // used only to resolve the IFR, so we should be ok.
+ return adapter->get_interface (TAO_ORB_Core_instance ()->orb (),
+ id.in ()
+ ACE_ENV_ARG_PARAMETER);
+}
+
+const char *
+TAO_DynamicImplementation::_interface_repository_id (void) const
+{
+ // This should never be called.
+ return 0;
+}
+
+void *
+TAO_DynamicImplementation::_downcast (const char *repository_id)
+{
+ ACE_UNUSED_ARG (repository_id);
+
+ // Don't know enough to do better.
+ return this;
+}
+
+TAO_Stub *
+TAO_DynamicImplementation::_create_stub (ACE_ENV_SINGLE_ARG_DECL)
+{
+ // If DynamicImplementation::_this() is invoked outside of the
+ // context of a request invocation on a target object being served
+ // by the DSI servant, it raises the PortableServer::WrongPolicy
+ // exception. See the CORBA C++ mapping, section 1.38.3.
+ TAO::Portable_Server::POA_Current_Impl *poa_current_impl =
+ static_cast <TAO::Portable_Server::POA_Current_Impl *>
+ (TAO_TSS_Resources::instance ()->poa_current_impl_);
+
+ if (poa_current_impl == 0
+ || this != poa_current_impl->servant ())
+ {
+ ACE_THROW_RETURN (PortableServer::POA::WrongPolicy (),
+ 0);
+ }
+
+ PortableServer::POA_var poa =
+ poa_current_impl->get_POA ();
+
+ CORBA::PolicyList_var client_exposed_policies =
+ poa_current_impl->poa ()->client_exposed_policies (
+ poa_current_impl->priority ()
+ ACE_ENV_ARG_PARAMETER
+ );
+ ACE_CHECK_RETURN (0);
+
+ CORBA::RepositoryId_var pinterface =
+ this->_primary_interface (poa_current_impl->object_id (),
+ poa.in ()
+ ACE_ENV_ARG_PARAMETER);
+ ACE_CHECK_RETURN (0);
+
+ return
+ poa_current_impl->poa ()->key_to_stub (poa_current_impl->object_key (),
+ pinterface.in (),
+ poa_current_impl->priority ()
+ ACE_ENV_ARG_PARAMETER);
+}
+
+void
+TAO_DynamicImplementation::_dispatch (TAO_ServerRequest &request,
+ void * /* context */
+ ACE_ENV_ARG_DECL)
+{
+ // No need to do any of this if the client isn't waiting.
+ if (request.response_expected ())
+ {
+ if (!CORBA::is_nil (request.forward_location ()))
+ {
+ request.init_reply ();
+ request.tao_send_reply ();
+
+ // No need to invoke in this case.
+ return;
+ }
+ else if (request.sync_with_server ())
+ {
+ // The last line before the call to this function
+ // was an ACE_CHECK_RETURN, so if we're here, we
+ // know there is no exception so far, and that's all
+ // a SYNC_WITH_SERVER client request cares about.
+ request.send_no_exception_reply ();
+ }
+ }
+
+ // Create DSI request object.
+ CORBA::ServerRequest *dsi_request = 0;
+ ACE_NEW (dsi_request,
+ CORBA::ServerRequest (request));
+
+ ACE_TRY
+ {
+ // Delegate to user.
+ this->invoke (dsi_request
+ ACE_ENV_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+
+ // Only if the client is waiting.
+ if (request.response_expected () && !request.sync_with_server ())
+ {
+ dsi_request->dsi_marshal (ACE_ENV_SINGLE_ARG_PARAMETER);
+ ACE_TRY_CHECK;
+ }
+ }
+ ACE_CATCH (CORBA::Exception, ex)
+ {
+ // Only if the client is waiting.
+ if (request.response_expected () && !request.sync_with_server ())
+ {
+ request.tao_send_reply_exception (ex);
+ }
+ }
+ ACE_ENDTRY;
+
+ ::CORBA::release (dsi_request);
+}
+
+CORBA::RepositoryId
+TAO_DynamicImplementation::get_id_from_primary_interface (
+ ACE_ENV_SINGLE_ARG_DECL
+ )
+{
+ // If this method is called outside of the
+ // context of a request invocation on a target object being served
+ // by the DSI servant, it raises the PortableServer::WrongPolicy
+ // exception. See the CORBA C++ mapping, section 1.38.3.
+ TAO::Portable_Server::POA_Current_Impl *poa_current_impl =
+ static_cast <TAO::Portable_Server::POA_Current_Impl *>
+ (TAO_TSS_Resources::instance ()->poa_current_impl_);
+
+ if (poa_current_impl == 0
+ || this != poa_current_impl->servant ())
+ {
+ ACE_THROW_RETURN (PortableServer::POA::WrongPolicy (),
+ 0);
+ }
+
+ PortableServer::POA_var poa =
+ poa_current_impl->get_POA ();
+
+ return this->_primary_interface (poa_current_impl->object_id (),
+ poa.in ()
+ ACE_ENV_ARG_PARAMETER);
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL