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