1 /*-----------------------------------------------------------------------------
2 Name: NameServerControl.h
3 Project: xmlBlaster.org
4 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
5 Comment: Helper to handle the NameServer stuff (bind, unbind, resolve ...)
6 Author: <Michele Laghi> laghi@swissinfo.org
7 -----------------------------------------------------------------------------*/
8
9 #ifndef _CLIENT_PROTOCOL_CORBA_NAMESERVERCONTROL_H
10 #define _CLIENT_PROTOCOL_CORBA_NAMESERVERCONTROL_H
11
12
13
14 #include <vector>
15 #ifndef STLPORT // Is automatically set by STLport if used, problem is on Linux/g++: STLport-4.5.1/stlport/stl/_algo.h:180: declaration of `operator MICO_LongDouble' as non-function
16 # include <algorithm>
17 #endif
18
19 #include <client/protocol/corba/CompatibleCorba.h> // client side headers
20 #include COSNAMING
21
22 #include <util/StringStripper2.h>
23 #include <util/XmlBlasterException.h>
24
25 typedef std::vector<std::string> ListType;
26
27 namespace org { namespace xmlBlaster {
28 namespace client { namespace protocol { namespace corba {
29
30 /**
31 * Class NameServerControl is used to encapsulate methods to access a Name
32 * Server (like binding, unbinding, name resolving...). It is a helper which
33 * makes such accesses easier (and less exceptions to take care of).
34 */
35
36 class Dll_Export NameServerControl {
37
38 private:
39
40 std::string me() {
41 return "NameServerControl";
42 }
43
44 CosNaming::NamingContext_var namingContext_;
45 org::xmlBlaster::util::StringStripper2 stripper_;
46
47 public:
48 /**
49 * This contructor takes the orb (which must be a valid orb) and two
50 * std::string separators. It retrieves a reference to the NameServer
51 * sep1: is the main separator, i.e. which separates the names from
52 * each other.
53 * sep2: is the std::string which separates the name (or id) from the kind
54 */
55 NameServerControl(CORBA::ORB_ptr orb, std::string sep1="/", std::string sep2=".") : stripper_(sep1,sep2) {
56 // Get naming service
57 CORBA::Object_var obj; // = (CORBA::Object_var)0;
58 try {
59 obj = orb->resolve_initial_references("NameService");
60 }
61
62 catch(const CORBA::ORB::InvalidName ex) {
63 # ifndef XMLBLASTER_OMNIORB
64 std::cerr << "Thrown invalid name exception: " << ex << std::endl;
65 # endif
66 std::string txt = me() + ".NameServerControl()";
67 std::string msg = "can't resolve the NameService";
68 throw org::xmlBlaster::util::XmlBlasterException("communication.noConnection", "client", txt, "en", msg);
69 }
70
71 if(CORBA::is_nil(obj.in())) {
72 std::string txt = me() + ".NameServerControl()";
73 std::string msg = "NameService in not a nil reference";
74 throw org::xmlBlaster::util::XmlBlasterException("communication.noConnection", "client", txt, "en", msg);
75 }
76
77 try {
78 namingContext_ = CosNaming::NamingContext::_narrow(obj.in());
79 }
80 catch (const CORBA::Exception & ex) {
81 std::string msg="Corba Exception " + to_string(ex);
82 std::string txt = me() + ".NameServerControl()";
83 throw org::xmlBlaster::util::XmlBlasterException("communication.noConnection", "client", txt, "en", msg);
84 }
85
86 if(CORBA::is_nil(namingContext_.in())) {
87 std::string txt = me() + ".NameServerControl()";
88 std::string msg = "NameService is not a NamingContext reference";
89 throw org::xmlBlaster::util::XmlBlasterException("communication.noConnection", "client", txt, "en", msg);
90 }
91 }
92
93 /**
94 * @param relativeContext A relative context in the name service
95 * @see Other constructor
96 */
97 NameServerControl(CosNaming::NamingContext_var &relativeContext, std::string sep1="/", std::string sep2=".") :
98 namingContext_(relativeContext), stripper_(sep1,sep2) {
99 }
100
101 /**
102 * @param name of type "xmlBlaster.MOM/heron.MOM" sep1="/", sep2="."
103 * @return never CORBA::nil
104 * @exception On problems or if reference is nil
105 * @see #resolve(CosNaming::Name &)
106 */
107 CORBA::Object_ptr resolve(const std::string &name) {
108 std::vector<std::pair<std::string,std::string> > nameVector = stripper_.strip(name);
109 CosNaming::Name objectName;
110 objectName.length(nameVector.size());
111 for (std::string::size_type i=0; i < nameVector.size(); i++) {
112 objectName[i].id =
113 CORBA::string_dup(nameVector[i].first.c_str());
114 objectName[i].kind =
115 CORBA::string_dup(nameVector[i].second.c_str());
116 }
117 return resolve(objectName);
118 }
119
120 /**
121 * Used to resolve a given name. Returns a reference to the object if an
122 * object with the given name exists. Otherwise returns zero.
123 * The caller is responsible to free the pointer.
124 * @param nameComponent
125 * @return never CORBA::nil, you need to free it!
126 * @exception On problems or if reference is nil
127 */
128 CORBA::Object_ptr resolve(CosNaming::Name &nameComponent) {
129 try {
130 CORBA::Object_ptr obj = namingContext_->resolve(nameComponent);
131 if (CORBA::is_nil(obj)) {
132 std::string txt = "Can't resolve CORBA NameService entry for '" +
133 NameServerControl::getString(nameComponent) +"', entry is nil";
134 //log_.error(me() + ".NoAuthService", txt);
135 throw org::xmlBlaster::util::XmlBlasterException("communication.noConnection",
136 "client", me(), "en", txt);
137 }
138 return obj;
139 }
140 catch(const CosNaming::NamingContext::NotFound& ex) {
141 std::string txt = me() + ".resolve()";
142 std::string msg = "CORBA CosNaming::NamingContext::NotFound - name not found exception '" + NameServerControl::getString(nameComponent) + "': " + to_string(ex);
143 throw org::xmlBlaster::util::XmlBlasterException("communication.noConnection", "client", txt, "en", msg);
144 }
145 catch(const CosNaming::NamingContext::CannotProceed& ex) {
146 std::string txt = me() + ".bind()";
147 std::string msg = "CORBA CosNaming::NamingContext::CannotProceed '" + NameServerControl::getString(nameComponent) + "': " + to_string(ex);
148 throw org::xmlBlaster::util::XmlBlasterException("communication.noConnection", "client", txt, "en", msg);
149 }
150 catch(const CosNaming::NamingContext::InvalidName & ex) {
151 std::string txt = me() + ".bind()";
152 std::string msg = "CORBA CosNaming::NamingContext::InvalidName '" + NameServerControl::getString(nameComponent) + "': " + to_string(ex);
153 throw org::xmlBlaster::util::XmlBlasterException("communication.noConnection", "client", txt, "en", msg);
154 }
155 }
156
157 /**
158 * @param id For example "xmlBlaster"
159 * @param kind For example "MOM"
160 * @return never CORBA::nil
161 * @see #resolve(CosNaming::Name &)
162 */
163 CORBA::Object_ptr resolve(const std::string &id, const std::string &kind) {
164 CosNaming::Name objectName;
165 objectName.length(1);
166 objectName[0].id = CORBA::string_dup(id.c_str());
167 objectName[0].kind = CORBA::string_dup(kind.c_str());
168 return resolve(objectName);
169 }
170
171 /**
172 * Returns the naming service reference
173 * Caller needs to free instance (typically by assigning it to a _var).
174 */
175 CosNaming::NamingContext_ptr getNamingService() {
176 return CosNaming::NamingContext::_duplicate(static_cast<CosNaming::NamingContext_ptr>(namingContext_.in()));
177 }
178
179 /**
180 * Creates a std::string representation of a NameService name hierarchy.
181 * This is useful for logging
182 * @return e.g. "xmlBlaster.MOM/heron.MOM"
183 */
184 static std::string getString(CosNaming::Name nameComponent, std::string sep1="/", std::string sep2=".") {
185 std::string ret = "";
186 for(CORBA::ULong i=0; i<nameComponent.length(); i++) {
187 if (i > 0) {
188 ret += sep1;
189 }
190 ret += std::string(nameComponent[i].id) +
191 ((nameComponent[i].kind != 0 && *nameComponent[i].kind != 0) ?
192 std::string(sep2) + std::string(nameComponent[i].kind) : std::string(""));
193 }
194 return ret;
195 }
196
197 /**
198 * Creates a std::string representation of a NameService name hierarchy.
199 * This is useful for logging
200 * @param id "xmlBlaster"
201 * @param kind "MOM"
202 * @return e.g. "xmlBlaster.MOM" with sep2_=="."
203 */
204 static std::string getString(const std::string &id, const std::string &kind, std::string sep2=".") {
205 return id + ((kind.size() > 0) ? std::string(sep2) + kind : std::string(""));
206 }
207
208 }; // class NameServerControl
209
210 }}}}} // namespace
211
212 #endif
syntax highlighted by Code2HTML, v. 0.9.1