summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/ImplRepo_Service/INS_Locator.cpp
blob: 58562921a105179ae8c88f78d1565d92eb8e2bf9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
//=============================================================================
/**
*  @file   INS_Locator.cpp
*
*  $Id$
*
*  @brief  Implementation of the ImR's INS Locator class
*
*  @author Darrell Brunsch <brunsch@cs.wustl.edu>
*/
//=============================================================================

#include "INS_Locator.h"
#include "ImR_Locator_i.h"
#include "tao/ORB_Constants.h"

INS_Locator::INS_Locator (ImR_Locator_i& loc)
: imr_locator_ (loc)
{
}

char *
INS_Locator::locate (const char* object_key)
{
  ACE_ASSERT (object_key != 0);
  try
    {
      ACE_CString key (object_key);
      ssize_t poaidx = key.find ('/');
      if (poaidx >= 0)
      {
        key = key.substring (0, poaidx);
      }

      if (imr_locator_.debug () > 1)
        ACE_DEBUG ((LM_DEBUG,
                    ACE_TEXT ("ImR: Activating server <%s>.\n"),
                    key.c_str ()));

      CORBA::String_var located =
        this->imr_locator_.activate_server_by_object (key.c_str ());

      ACE_CString tmp = located.in ();
      tmp += object_key;

      if (imr_locator_.debug () > 0)
        ACE_DEBUG ((LM_DEBUG,
                    ACE_TEXT ("ImR: Forwarding invocation on <%s> to <%s>\n"),
                    key.c_str (), tmp.c_str()));

      return CORBA::string_dup (tmp.c_str ());
    }
  catch (const ImplementationRepository::CannotActivate&)
    {
      throw CORBA::TRANSIENT (
        CORBA::SystemException::_tao_minor_code (
          TAO_IMPLREPO_MINOR_CODE,
          0),
        CORBA::COMPLETED_NO);
    }
  catch (const ImplementationRepository::NotFound&)
    {
      ACE_CString objkey (object_key);

      // check to see if there are more slashes beyond the first one
      ssize_t poaidx2 = objkey.rfind ('/');
      ssize_t poaidx1 = objkey.find ('/');
      if (poaidx1 <= 0 || poaidx2 <= 0 || poaidx1 == poaidx2)
        {
          throw CORBA::TRANSIENT (
            CORBA::SystemException::_tao_minor_code (
              TAO_IMPLREPO_MINOR_CODE,
              0),
            CORBA::COMPLETED_NO);
        }

      // remove the data field beyond the last delimiter
      // which is assumed to be the object id.
      ACE_CString key2 = objkey.substring(0, poaidx2);
      while (poaidx2 > poaidx1)
        {
          try
            {
              if (imr_locator_.debug () > 1)
                {
                  ACE_DEBUG ((LM_DEBUG,
                    ACE_TEXT ("ImR: Try activating server using <%s>.\n"),
                    key2.c_str ()));
                }

              CORBA::String_var located =
                this->imr_locator_.activate_server_by_object (key2.c_str ());

              ACE_CString tmp = located.in ();
              tmp += object_key;

              if (imr_locator_.debug () > 0)
                {
                  ACE_DEBUG ((LM_DEBUG,
                              ACE_TEXT ("ImR: Forwarding invocation on <%s> ")
                              ACE_TEXT ("to <%s>\n"), key2.c_str (), tmp.c_str()));
                }

              return CORBA::string_dup (tmp.c_str ());
            }
          catch (const ImplementationRepository::CannotActivate&)
            {
              throw CORBA::TRANSIENT (
                CORBA::SystemException::_tao_minor_code (
                  TAO_IMPLREPO_MINOR_CODE,
                  0),
                CORBA::COMPLETED_NO);
            }
          catch (const ImplementationRepository::NotFound&)
            {
              poaidx2 = key2.rfind ('/');
              if (poaidx2 > poaidx1)
                {
                  // continue to try again
                  key2 = key2.substring(0, poaidx2);
                  continue;
                }
              else
                {
                  break;
                }
            }
        } // while()

      //  No match is found
      throw CORBA::TRANSIENT (CORBA::SystemException::_tao_minor_code (
                                TAO_IMPLREPO_MINOR_CODE,
                                0),
                              CORBA::COMPLETED_NO);
    }
}