hpp-corbaserver  4.15.1
Corba server for Humanoid Path Planner applications
servant-base.hh
Go to the documentation of this file.
1 // Copyright (C) 2019 by Joseph Mirabel, LAAS-CNRS.
2 //
3 
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // 1. Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright
12 // notice, this list of conditions and the following disclaimer in the
13 // documentation and/or other materials provided with the distribution.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
26 // DAMAGE.
27 //
28 // This software is provided "as is" without warranty of any kind,
29 // either expressed or implied, including but not limited to the
30 // implied warranties of fitness for a particular purpose.
31 //
32 // See the COPYING file for more information.
33 
34 #ifndef HPP_CORBASERVER_SERVANT_BASE_HH
35 #define HPP_CORBASERVER_SERVANT_BASE_HH
36 
37 #include <hpp/common-idl.hh>
39 
40 namespace hpp {
41 namespace corbaServer {
72 
73 #define SERVANT_BASE_TYPEDEFS(idlObj, hppObj) \
74  protected: \
75  using ::hpp::corbaServer::AbstractServantBase<hppObj>::server_; \
76  \
77  public: \
78  typedef _Base Base; \
79  typedef _Storage Storage; \
80  typedef idlObj Object; \
81  typedef idlObj##_ptr Object_ptr; \
82  typedef idlObj##_var Object_var; \
83  typedef ::hpp::corbaServer::ServantBase<hppObj, _Storage> _ServantBase; \
84  using _ServantBase::get; \
85  using _ServantBase::getT; \
86  using _ServantBase::getS
87 
88 template <typename T>
89 struct hpp_traits {};
90 
93  public:
94  virtual Server::ServantKey getServantKey() const = 0;
95 };
96 
101 template <typename T>
103  public:
104  virtual ~AbstractServantBase() {}
105 
106  typedef shared_ptr<T> TShPtr_t;
107  typedef weak_ptr<T> TWkPtr_t;
108 
109  virtual TShPtr_t get() const = 0;
110 
111  virtual Server::ServantKey getServantKey() const { return get().get(); }
112 
113  protected:
114  AbstractServantBase(Server* server) : server_(server) {}
115 
117 };
118 
119 template <typename T, typename _Storage>
120 class ServantBase : public AbstractServantBase<T> {
121  public:
122  typedef _Storage Storage;
123  using typename AbstractServantBase<T>::TShPtr_t;
124  using typename AbstractServantBase<T>::TWkPtr_t;
125  typedef weak_ptr<typename Storage::element_type> StorageElementWkPtr_t;
126  typedef shared_ptr<typename Storage::element_type> StorageElementShPtr_t;
127 
128  virtual ~ServantBase() {}
129 
130  virtual TShPtr_t get() const {
131  TWkPtr_t wk((StorageElementWkPtr_t)wrappedObject_);
132  if (wk.expired()) {
133  // Object expired. Remove the servant and throw.
134  objectExpired();
135  }
136  return wk.lock();
137  }
138 
139  StorageElementShPtr_t getT() const {
140  StorageElementWkPtr_t wk((StorageElementWkPtr_t)wrappedObject_);
141  if (wk.expired()) {
142  // Object expired. Remove the servant and throw.
143  objectExpired();
144  }
145  return wk.lock();
146  }
147 
148  const Storage& getS() const { return wrappedObject_; }
149 
151  void persistantStorage(bool persistant) {
152  if (persistant)
153  p_ = get();
154  else
155  p_.reset();
156  }
157 
159  bool persistantStorage() const { return p_; }
160 
161  void deleteThis() {
162  persistantStorage(false);
163 
164  // Object expired. Try to remove the server.
165  PortableServer::Servant servant =
166  dynamic_cast<PortableServer::Servant>(this);
167  if (servant == NULL)
168  throw Error("The object was deleted. I could not delete the servant.");
169  this->server_->removeServant(servant);
170  // Deactivate object
171  PortableServer::ObjectId_var objectId =
172  this->server_->poa()->servant_to_id(servant);
173  this->server_->poa()->deactivate_object(objectId.in());
174  }
175 
176  protected:
177  ServantBase(Server* server, const Storage& _s)
178  : AbstractServantBase<T>(server), wrappedObject_(_s) {
179  persistantStorage(true);
180  }
181 
182  Storage wrappedObject_;
183 
184  private:
185  void objectExpired() const {
186  // Object expired. Try to remove the server.
187  PortableServer::Servant servant =
188  dynamic_cast<PortableServer::Servant>(const_cast<ServantBase*>(this));
189  if (servant == NULL)
190  throw Error("The object was deleted. I could not delete the servant.");
191  this->server_->removeServant(servant);
192  // Deactivate object
193  PortableServer::ObjectId_var objectId =
194  this->server_->poa()->servant_to_id(servant);
195  this->server_->poa()->deactivate_object(objectId.in());
196  throw Error("The object has been deleted. I delete the servant.");
197  }
198 
199  TShPtr_t p_;
200 };
201 
217 template <typename T, typename Base>
219  public:
220  typedef weak_ptr<T> ptr_t;
221 
222  ptr_t element;
223 
224  AbstractStorage(const ptr_t& _element) : element(_element) {}
225  operator shared_ptr<T>() const { return element.lock(); }
226  operator weak_ptr<T>() const { return element; }
227  long use_count() const { return element.use_count(); }
228 
229  // Mimic shared_ptr<D> interface:
230  typedef T element_type;
231  operator bool() const { return use_count() > 0; }
232 };
233 
234 typedef PortableServer::Servant_var<PortableServer::ServantBase>
236 
237 template <typename S, typename P>
238 PortableServer::Servant_var<S> reference_to_servant(Server* server,
239  const P& p) {
240  PortableServer::Servant s = server->poa()->reference_to_servant(p);
241  if (s == NULL) throw Error("The servant is not located here");
242  return dynamic_cast<S*>(s);
243 }
244 
247 template <typename T, typename P>
249  ServantBase_var s = server->poa()->reference_to_servant(p);
250  if (s.in() == NULL) throw Error("The servant is not located here");
251  return dynamic_cast<AbstractServantBase<T>*>(s.in());
252 }
253 
263 template <typename P, typename S>
264 P makeServant(Server* server, S* s) {
265  Server::ServantKey servantKey = s->getServantKey();
266  S* servant = dynamic_cast<S*>(server->getServant(servantKey));
267  if (servant != NULL) {
268  delete s;
269  return servant->_this();
270  }
271 
272  PortableServer::Servant_var<S> d(s);
273  // ObjectId_var object is here to delete the servantId.
274  PortableServer::ObjectId_var servantId = server->poa()->activate_object(d);
275  (void)servantId;
276 
277  server->addServantKeyAndServant(servantKey, d.in());
278  return d->_this();
279 }
280 
282 namespace details {
284 template <typename U, typename V, template <typename> class StorageTpl>
285 struct storage_cast_impl {
286  static StorageTpl<U> run(const StorageTpl<V>& o) {
287  return o.template cast<U>();
288  }
289 };
290 
292 template <typename U, typename V>
293 struct storage_cast_impl<U, V, shared_ptr> {
294  static shared_ptr<U> run(const shared_ptr<V>& o) {
295  return dynamic_pointer_cast<U>(o);
296  }
297 };
298 
300 template <typename U, typename V>
301 struct storage_cast_impl<U, V, weak_ptr> {
302  static weak_ptr<U> run(const weak_ptr<V>& o) {
303  return dynamic_pointer_cast<U>(o.lock());
304  }
305 };
306 } // namespace details
308 
310 template <typename U, typename V, template <typename> class StorageTpl>
311 static StorageTpl<U> storage_cast(const StorageTpl<V>& o) {
312  return details::storage_cast_impl<U, V, StorageTpl>::run(o);
313 }
314 
317 template <typename T, typename P>
318 auto reference_to_object(Server* server, const P& p) {
319  ServantBase_var s = server->poa()->reference_to_servant(p);
320  if (s.in() == NULL) throw Error("The servant is not located here");
321  typedef typename hpp_traits<T>::Base TBase;
323  dynamic_cast<AbstractServantBase<TBase>*>(s.in());
324  if (asb == NULL) throw Error("Not an object of the correct type.");
325  auto ret = storage_cast<T>(asb->get());
326  if (!ret) throw Error("Object is not of the correct type.");
327  return ret;
328 }
329 
333 template <typename ServantBaseType>
335  public:
336  typedef typename ServantBaseType::Storage Storage;
337  typedef typename ServantBaseType::Object_var Object_var;
338 
339  ServantFactoryBase(const size_type& depth) : depth_(depth) {}
340 
341  virtual Object_var servant(Server* server, const Storage& obj) = 0;
342 
346  size_type depth() const { return depth_; }
347 
348  private:
349  size_type depth_;
350 };
351 
352 template <typename ServantBaseType, typename ServantType>
353 struct ServantFactory : ServantFactoryBase<ServantBaseType> {
354  typedef typename ServantBaseType::Object_var Object_var;
355  typedef typename ServantBaseType::Storage StorageBase;
356 
357  ServantFactory(const size_type& depth)
358  : ServantFactoryBase<ServantBaseType>(depth) {}
359 
360  virtual Object_var servant(Server* s, const StorageBase& o) {
361  typedef typename ServantType::Storage Storage;
362  Storage u = storage_cast<typename Storage::element_type>(o);
363  Object_var ret;
364  if (u.use_count() > 0)
365  ret = makeServant<Object_var>(s, new ServantType(s, u));
366  return ret;
367  }
368 };
369 
370 template <typename ServantBaseType>
371 std::vector<ServantFactoryBase<ServantBaseType>*>& objectDowncasts();
372 
373 template <typename ServantBaseType>
375  typedef std::vector<ServantFactoryBase<ServantBaseType>*> vector_t;
376  typedef typename vector_t::iterator iterator;
377 
378  vector_t& vec = objectDowncasts<ServantBaseType>();
379  size_type d = object->depth();
380  for (iterator _obj = vec.begin(); _obj != vec.end(); ++_obj) {
381  if (d >= (*_obj)->depth()) {
382  vec.insert(_obj, object);
383  return;
384  }
385  }
386  vec.push_back(object);
387 }
388 
391 template <typename ServantBaseType, typename ReturnType>
392 typename ReturnType::Object_var makeServantDownCast(
393  Server* server, const typename ServantBaseType::Storage& t) {
394  typedef typename ServantBaseType::Object_var BaseObject_var;
395  typedef typename ReturnType::Object_var Object_var;
396  BaseObject_var servant;
397  assert(CORBA::Object_Helper::is_nil(servant.in()));
398 
399  typedef std::vector<ServantFactoryBase<ServantBaseType>*> vector_t;
400  typedef typename vector_t::iterator iterator;
401 
402  vector_t& vec = objectDowncasts<ServantBaseType>();
403  for (iterator _obj = vec.begin(); _obj != vec.end(); ++_obj) {
404  servant = (*_obj)->servant(server, t);
405  if (!CORBA::Object_Helper::is_nil(servant.in())) {
406  // Cast to child type.
407  return Object_var(ReturnType::Object::_narrow(servant._retn()));
408  }
409  }
410  return Object_var();
411 }
412 
413 template <typename ServantBaseType>
414 typename ServantBaseType::Object_var makeServantDownCast(
415  Server* server, const typename ServantBaseType::Storage& t) {
416  // TODO
417  // return makeServantDownCast <ServantBaseType, ServantBaseType> (server, t);
418  typedef typename ServantBaseType::Object_var Object_var;
419  Object_var servant;
420  assert(CORBA::Object_Helper::is_nil(servant.in()));
421 
422  typedef std::vector<ServantFactoryBase<ServantBaseType>*> vector_t;
423  typedef typename vector_t::iterator iterator;
424 
425  vector_t& vec = objectDowncasts<ServantBaseType>();
426  for (iterator _obj = vec.begin(); _obj != vec.end(); ++_obj) {
427  servant = (*_obj)->servant(server, t);
428  if (!CORBA::Object_Helper::is_nil(servant.in())) break;
429  }
430 
431  return servant;
432 }
433 
434 template <typename OutType, typename InnerBaseType,
435  typename InnerType = InnerBaseType>
438 
439  vectorToSeqServant(Server* _s) : wrappedObject_(_s) {}
440 
441  template <typename InContainer>
442  inline OutType* operator()(const InContainer& input) {
443  std::size_t len = std::distance(input.begin(), input.end());
444  OutType* seq = new OutType();
445  seq->length((CORBA::ULong)len);
446 
447  std::size_t i = 0;
448  typename InContainer::const_iterator it = input.begin();
449  while (it != input.end()) {
450  (*seq)[(CORBA::ULong)i] =
451  makeServantDownCast<InnerBaseType, InnerType>(wrappedObject_, *it)
452  ._retn();
453  ++it;
454  ++i;
455  }
456  return seq;
457  }
458 };
459 
461 } // end of namespace corbaServer.
462 } // end of namespace hpp.
463 
472 #define HPP_CORBASERVER_ADD_DOWNCAST_OBJECT(ServantType, BaseServantType, \
473  depth) \
474  struct HPP_CORE_DLLAPI __InitializerClass_##ServantType { \
475  __InitializerClass_##ServantType() { \
476  ::hpp::corbaServer::addDowncastObjects<BaseServantType>( \
477  new ::hpp::corbaServer::ServantFactory<BaseServantType, \
478  ServantType>(depth)); \
479  } \
480  }; \
481  HPP_CORBASERVER_DLLLOCAL __InitializerClass_##ServantType \
482  __instance_##ServantType;
483 
484 #endif // HPP_CORBASERVER_SERVANT_BASE_HH
Definition: servant-base.hh:120
auto reference_to_object(Server *server, const P &p)
Definition: servant-base.hh:318
PortableServer::Servant_var< PortableServer::ServantBase > ServantBase_var
Definition: servant-base.hh:235
std::vector< ServantFactoryBase< ServantBaseType > * > & objectDowncasts()
ServantFactory(const size_type &depth)
Definition: servant-base.hh:357
Definition: servant-base.hh:353
ServantBaseType::Object_var Object_var
Definition: servant-base.hh:337
Implement CORBA interface ``Obstacle&#39;&#39;.
Definition: client.hh:46
AbstractServantBase(Server *server)
Definition: servant-base.hh:114
weak_ptr< typename Storage::element_type > StorageElementWkPtr_t
Definition: servant-base.hh:125
AbstractServantBase< T > * reference_to_servant_base(Server *server, const P &p)
Definition: servant-base.hh:248
T element_type
Definition: servant-base.hh:230
ptr_t element
Definition: servant-base.hh:222
size_type depth() const
Definition: servant-base.hh:346
Abstract class used to avoid duplication of the servants.
Definition: servant-base.hh:92
PortableServer::Servant_var< S > reference_to_servant(Server *server, const P &p)
Definition: servant-base.hh:238
virtual TShPtr_t get() const =0
void addServantKeyAndServant(ServantKey servantKey, PortableServer::Servant servant)
Server * server_
Definition: servant-base.hh:116
Corba exception travelling through the Corba channel.
Definition: common.idl:26
Storage wrappedObject_
Definition: servant-base.hh:182
Definition: servant-base.hh:218
OutType * operator()(const InContainer &input)
Definition: servant-base.hh:442
bool persistantStorage() const
See persistantStorage(bool)
Definition: servant-base.hh:159
Definition: servant-base.hh:334
void addDowncastObjects(ServantFactoryBase< ServantBaseType > *const object)
Definition: servant-base.hh:374
pinocchio::vector_t vector_t
Definition: fwd.hh:109
const Storage & getS() const
Definition: servant-base.hh:148
ReturnType::Object_var makeServantDownCast(Server *server, const typename ServantBaseType::Storage &t)
Definition: servant-base.hh:392
PortableServer::POA_var poa()
Definition: server.hh:110
ServantBase(Server *server, const Storage &_s)
Definition: servant-base.hh:177
P makeServant(Server *server, S *s)
Definition: servant-base.hh:264
Server * wrappedObject_
Definition: servant-base.hh:437
AbstractStorage(const ptr_t &_element)
Definition: servant-base.hh:224
ServantBaseType::Object_var Object_var
Definition: servant-base.hh:354
virtual ~ServantBase()
Definition: servant-base.hh:128
vectorToSeqServant(Server *_s)
Definition: servant-base.hh:439
Definition: servant-base.hh:436
virtual Object_var servant(Server *s, const StorageBase &o)
Definition: servant-base.hh:360
weak_ptr< T > ptr_t
Definition: servant-base.hh:220
ServantBaseType::Storage StorageBase
Definition: servant-base.hh:355
Implementation of Hpp module Corba server.
Definition: server.hh:77
virtual Server::ServantKey getServantKey() const
Definition: servant-base.hh:111
PortableServer::Servant getServant(ServantKey servantKey) const
shared_ptr< typename Storage::element_type > StorageElementShPtr_t
Definition: servant-base.hh:126
Definition: servant-base.hh:102
void persistantStorage(bool persistant)
Set to true if the servant should take ownership of this object.
Definition: servant-base.hh:151
void * ServantKey
Definition: server.hh:157
Definition: servant-base.hh:89
shared_ptr< T > TShPtr_t
Definition: servant-base.hh:106
_Storage Storage
Definition: servant-base.hh:122
StorageElementShPtr_t getT() const
Definition: servant-base.hh:139
_CORBA_MODULE hpp _CORBA_MODULE_BEG _CORBA_MODULE core_idl _CORBA_MODULE_BEG typedef ::CORBA::ULongLong size_t
Definition: paths-idl.hh:75
void deleteThis()
Definition: servant-base.hh:161
weak_ptr< T > TWkPtr_t
Definition: servant-base.hh:107
ServantBaseType::Storage Storage
Definition: servant-base.hh:336
long use_count() const
Definition: servant-base.hh:227
pinocchio::size_type size_type
Definition: fwd.hh:112
virtual ~AbstractServantBase()
Definition: servant-base.hh:104
ServantFactoryBase(const size_type &depth)
Definition: servant-base.hh:339