PersistentObjectClassSegment.h
Go to the documentation of this file.
1 /*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @package MemoryX::WorkingMemory
17 * @author Kai Welke ( welke at kit dot edu)
18 * @date 2012
19 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20 * GNU General Public License
21 */
22 
23 #pragma once
24 
26 
28 
29 #include <MemoryX/interface/core/EntityBase.h>
30 #include <MemoryX/interface/memorytypes/MemoryEntities.h>
31 #include <MemoryX/interface/memorytypes/MemorySegments.h>
33 
34 #include <vector>
35 
36 namespace memoryx
37 {
38  /**
39  * The persistent object class segment is a specialized segment of the SegmentedMemory.
40  * It keeps object classes which are held in prior knowledge (MongoDB) and thus are persistent.
41  * This segment is usually part of the prior knowledge memory.
42  */
44  virtual public PersistentEntitySegment,
45  virtual public PersistentObjectClassSegmentBase
46  {
47  public:
48  /**
49  * Creates a new peristent object class segment.
50  *
51  * @param entityCollection a proxy to the collection from commonstorage
52  * @param ic ice communicator
53  * @param useMongoIds whether to use entity IDs stored in MongoDB or internal ids
54  */
55  PersistentObjectClassSegment(CollectionInterfacePrx entityCollection, Ice::CommunicatorPtr ic, bool useMongoIds = true) :
56  PersistentEntitySegment(entityCollection, ic, useMongoIds),
57  PersistentObjectClassSegmentBase()
58  {
59  }
60 
61  /**
62  * Retrieve a persistent object class by id
63  *
64  * @param id either mongoId (if useMongIds) or internal id
65  * @return pointer to object class on success
66  */
67  ObjectClassBasePtr getObjectClassById(const ::std::string& id, const ::Ice::Current& = Ice::emptyCurrent) const override
68  {
69  return ObjectClassBasePtr::dynamicCast(getEntityById(id));
70  }
71 
72  /**
73  * Retrieve a persistent object class by name
74  *
75  * @param name name of object class
76  * @return pointer to object class on success
77  */
78  ObjectClassBasePtr getObjectClassByName(const ::std::string& name, const ::Ice::Current& = Ice::emptyCurrent) const override
79  {
80  return ObjectClassBasePtr::dynamicCast(getEntityByName(name));
81  }
82 
83  /**
84  * @brief Retrieve a object class with all the parent classes,
85  * that means also the parent classes of the direct parent classes and so on.
86  * @param name Name of the object class to retrieve
87  * @return pointer to the object class
88  */
89  ObjectClassBasePtr getObjectClassByNameWithAllParents(const ::std::string& name, const ::Ice::Current& = Ice::emptyCurrent) const override
90  {
91  ObjectClassBasePtr objClass = ObjectClassBasePtr::dynamicCast(getEntityByName(name));
92 
93  if (!objClass)
94  {
95  ARMARX_ERROR_S << "No object class with name '" << name << "'";
96  return objClass;
97  }
98 
99  objClass->clearParentClasses();
100  ObjectClassList parents = getAllParentClasses(objClass->getName());
101 
102  if (objClass)
103  {
104  for (size_t i = 0; i < parents.size(); i++)
105  {
106  objClass->addParentClass(parents.at(i)->getName());
107  }
108  }
109 
110  return objClass;
111  }
112 
113  /**
114  * Retrieve child classes of a class
115  *
116  * @param parentClassName name of the parent
117  * @return list of child object classes
118  */
119  ObjectClassList getChildClasses(const std::string& parentClassName, const ::Ice::Current& = Ice::emptyCurrent) const override
120  {
121  ObjectClassList result;
122  EntityBaseList children = getEntitiesByAttrValue("parentClasses", parentClassName);
123 
124  for (EntityBaseList::const_iterator it = children.begin(); it != children.end(); ++it)
125  {
126  result.push_back(ObjectClassBasePtr::dynamicCast(*it));
127  }
128 
129  return result;
130  }
131 
132  /**
133  * Retrieve direct parent classes of a class
134  *
135  * @param parentClassName name of the parent
136  * @return list of child object classes
137  */
138  ObjectClassList getParentClasses(const std::string& className, const ::Ice::Current& = Ice::emptyCurrent) const override
139  {
140 
141  EntityBasePtr entity = getEntityByName(className);
142 
143  if (!entity)
144  {
145  throw armarx::LocalException("Could not find class with name ") << className;
146  }
147 
148  ObjectClassBasePtr objClass = ObjectClassBasePtr::dynamicCast(entity);
149 
150  if (!objClass)
151  {
152  throw armarx::LocalException("Could not cast class with name ") << className;
153  }
154 
155  NameList parentClassNameList = objClass->getParentClasses();
156  ObjectClassList parentClassList;
157 
158  for (NameList::const_iterator it = parentClassNameList.begin(); it != parentClassNameList.end(); ++it)
159  {
160  if (it->empty())
161  {
162  continue;
163  }
164 
165  ObjectClassBasePtr ptr = ObjectClassBasePtr::dynamicCast(getEntityByName(*it));
166 
167  if (!ptr)
168  {
169  ARMARX_INFO_S << "Could not cast parent " << *it << " of class " << className;
170  }
171  else
172  {
173  parentClassList.push_back(ptr);
174  }
175  }
176 
177  return parentClassList;
178  }
179 
180  /**
181  * Retrieve class and all subclasses. Retrieves a complete ontological subtree from the class prior knowledge.
182  *
183  * @param rootClassName name of the root class
184  * @return list of object classes in the subtree
185  */
186  ObjectClassList getClassWithSubclasses(const std::string& rootClassName, const ::Ice::Current& = Ice::emptyCurrent) const override
187  {
188  // iterate through classes
189  ObjectClassList relevantClasses;
190  ObjectClassPtr root = ObjectClassPtr::dynamicCast(getEntityByName(rootClassName));
191 
192  if (!root)
193  {
194  ARMARX_WARNING_S << "Parent Object Class '" << rootClassName << "' does not exist in segment!";
195  return ObjectClassList();
196  }
197 
198  relevantClasses.push_back(root);
199 
200  int index = 0;
201 
202  while (index != int(relevantClasses.size()))
203  {
204  ObjectClassBasePtr current = relevantClasses.at(index);
205 
206  // add children of this class
207  ObjectClassList childs = getChildClasses(current->getName());
208 
209  if (childs.size() != 0)
210  {
211  std::copy(childs.begin(), childs.end(), std::back_inserter(relevantClasses));
212  }
213 
214  index++;
215  }
216 
217  unique(relevantClasses);
218 
219  return relevantClasses;
220  }
221 
222  /**
223  * @brief Retrieves recursively all parent classes for an object class from the database.
224  * @param className Name of object class for which the parents should be calculated.
225  * @return List of parent objects
226  */
227  ObjectClassList getAllParentClasses(const std::string& className, const ::Ice::Current& = Ice::emptyCurrent) const override
228  {
229  ObjectClassList relevantClasses, classesLeftToCheck;
230 
231  ObjectClassBasePtr current = ObjectClassBasePtr::dynamicCast(getEntityByName(className));
232 
233  if (!current)
234  {
235  return relevantClasses;
236  }
237 
238  do
239  {
240  // add children of this class
241  if (!current)
242  {
243  throw armarx::LocalException("current is NULL!");
244  }
245 
246  // ARMARX_INFO_S << index << " Getting parents of " << current->getName();
247  ObjectClassList parents = getParentClasses(current->getName());
248 
249  if (parents.size() != 0)
250  {
251  std::copy(parents.begin(), parents.end(), std::back_inserter(relevantClasses));
252  std::copy(parents.begin(), parents.end(), std::back_inserter(classesLeftToCheck));
253  }
254  unique(classesLeftToCheck);
255  if (classesLeftToCheck.size() == 0)
256  {
257  break;
258  }
259  current = *classesLeftToCheck.rbegin();
260  classesLeftToCheck.pop_back();
261  }
262  while (true);
263 
264  unique(relevantClasses);
265  return relevantClasses;
266  }
267 
268  /**
269  * @brief Checks whether an object class is equal to another or if they contain an equal parent class
270  * @param objClass
271  * @param other
272  * @return
273  */
274  ObjectComparisonResult compare(const ObjectClassBasePtr& objClass, const ObjectClassBasePtr& other, const Ice::Current& = Ice::emptyCurrent) const override
275  {
276  if (other->getName() == objClass->getName())
277  {
278  return eEqualClass;
279  }
280 
281  ObjectClassList otherParentClasses = getAllParentClasses(other->getName());
282  ObjectClassList parentClasses = getAllParentClasses(objClass->getName());
283 
284  // check parents names
285  for (ObjectClassList::iterator itOther = otherParentClasses.begin(); itOther != otherParentClasses.end(); itOther++)
286  {
287  if (objClass->getName() == (*itOther)->getName()) // other is a subclass of this -> so its equal
288  {
289  return eEqualClass;
290  }
291 
292  for (ObjectClassList::iterator it = parentClasses.begin(); it != parentClasses.end(); it++)
293  {
294  if ((*it)->getName() == (*itOther)->getName()) // parent of this is equal to parent of other, so only equal parent class
295  {
296  return eEqualParentClass;
297  }
298  }
299  }
300 
301  for (ObjectClassList::iterator it = parentClasses.begin(); it != parentClasses.end(); it++)
302  {
303  if ((*it)->getName() == other->getName()) // other is parent class of objClass -> so only equal parent class
304  {
305  return eEqualParentClass;
306  }
307  }
308 
309  return eNotEqualClass;
310  }
311 
312  bool isParentClass(const ::std::string& className, const ::std::string& parentCandidate, const ::Ice::Current& = Ice::emptyCurrent) const override
313  {
314  ObjectClassList parentClasses = getAllParentClasses(className);
315 
316  for (const auto& parent : parentClasses)
317  {
318  if (parent->getName() == parentCandidate)
319  {
320  return true;
321  }
322  }
323 
324  return false;
325  }
326 
327  static void unique(ObjectClassList& classes)
328  {
329  auto objectClassPtrCompareLess = [](const ObjectClassBasePtr & lhs, const ObjectClassBasePtr & rhs)
330  {
331  return lhs->getName() < rhs->getName();
332  };
333  auto objectClassPtrCompareEq = [](const ObjectClassBasePtr & lhs, const ObjectClassBasePtr & rhs)
334  {
335  return lhs->getName() == rhs->getName();
336  };
337  std::sort(classes.begin(), classes.end(), objectClassPtrCompareLess);
338  auto newEnd = std::unique(classes.begin(), classes.end(), objectClassPtrCompareEq);
339  classes.erase(newEnd, classes.end());
340  }
341 
342  };
343 
345 
346 }
347 
memoryx::PersistentObjectClassSegment::getObjectClassById
ObjectClassBasePtr getObjectClassById(const ::std::string &id, const ::Ice::Current &=Ice::emptyCurrent) const override
Retrieve a persistent object class by id.
Definition: PersistentObjectClassSegment.h:67
cyberglove_with_calib_22dof.ic
ic
Definition: cyberglove_with_calib_22dof.py:22
index
uint8_t index
Definition: EtherCATFrame.h:59
PersistentEntitySegment.h
memoryx
VirtualRobot headers.
Definition: CommonPlacesTester.cpp:48
memoryx::PersistentObjectClassSegment::PersistentObjectClassSegment
PersistentObjectClassSegment(CollectionInterfacePrx entityCollection, Ice::CommunicatorPtr ic, bool useMongoIds=true)
Creates a new peristent object class segment.
Definition: PersistentObjectClassSegment.h:55
memoryx::PersistentObjectClassSegment
The persistent object class segment is a specialized segment of the SegmentedMemory.
Definition: PersistentObjectClassSegment.h:43
ObjectClass.h
memoryx::PersistentObjectClassSegment::getChildClasses
ObjectClassList getChildClasses(const std::string &parentClassName, const ::Ice::Current &=Ice::emptyCurrent) const override
Retrieve child classes of a class.
Definition: PersistentObjectClassSegment.h:119
memoryx::PersistentObjectClassSegment::getObjectClassByNameWithAllParents
ObjectClassBasePtr getObjectClassByNameWithAllParents(const ::std::string &name, const ::Ice::Current &=Ice::emptyCurrent) const override
Retrieve a object class with all the parent classes, that means also the parent classes of the direct...
Definition: PersistentObjectClassSegment.h:89
IceInternal::Handle< ::Ice::Communicator >
memoryx::PersistentObjectClassSegment::getClassWithSubclasses
ObjectClassList getClassWithSubclasses(const std::string &rootClassName, const ::Ice::Current &=Ice::emptyCurrent) const override
Retrieve class and all subclasses.
Definition: PersistentObjectClassSegment.h:186
ARMARXCOMPONENT_IMPORT_EXPORT
#define ARMARXCOMPONENT_IMPORT_EXPORT
Definition: ImportExportComponent.h:38
copy
Use of this software is granted under one of the following two to be chosen freely by the user Boost Software License Version Marcin Kalicinski Permission is hereby free of to any person or organization obtaining a copy of the software and accompanying documentation covered by this and transmit the and to prepare derivative works of the and to permit third parties to whom the Software is furnished to do all subject to the including the above license this restriction and the following must be included in all copies of the in whole or in and all derivative works of the unless such copies or derivative works are solely in the form of machine executable object code generated by a source language processor THE SOFTWARE IS PROVIDED AS WITHOUT WARRANTY OF ANY EXPRESS OR INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF FITNESS FOR A PARTICULAR TITLE AND NON INFRINGEMENT IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER WHETHER IN TORT OR ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE The MIT Marcin Kalicinski Permission is hereby free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to copy
Definition: license.txt:39
ARMARX_ERROR_S
#define ARMARX_ERROR_S
Definition: Logging.h:209
memoryx::PersistentObjectClassSegment::getObjectClassByName
ObjectClassBasePtr getObjectClassByName(const ::std::string &name, const ::Ice::Current &=Ice::emptyCurrent) const override
Retrieve a persistent object class by name.
Definition: PersistentObjectClassSegment.h:78
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:206
memoryx::PersistentObjectClassSegment::unique
static void unique(ObjectClassList &classes)
Definition: PersistentObjectClassSegment.h:327
memoryx::PersistentObjectClassSegment::getParentClasses
ObjectClassList getParentClasses(const std::string &className, const ::Ice::Current &=Ice::emptyCurrent) const override
Retrieve direct parent classes of a class.
Definition: PersistentObjectClassSegment.h:138
memoryx::PersistentObjectClassSegment::isParentClass
bool isParentClass(const ::std::string &className, const ::std::string &parentCandidate, const ::Ice::Current &=Ice::emptyCurrent) const override
Definition: PersistentObjectClassSegment.h:312
memoryx::PersistentEntitySegment
The PersistentEntitySegment class is the base class for all memory segments containing memoryx::Entit...
Definition: PersistentEntitySegment.h:107
ARMARX_INFO_S
#define ARMARX_INFO_S
Definition: Logging.h:195
memoryx::PersistentObjectClassSegment::getAllParentClasses
ObjectClassList getAllParentClasses(const std::string &className, const ::Ice::Current &=Ice::emptyCurrent) const override
Retrieves recursively all parent classes for an object class from the database.
Definition: PersistentObjectClassSegment.h:227
memoryx::PersistentObjectClassSegment::compare
ObjectComparisonResult compare(const ObjectClassBasePtr &objClass, const ObjectClassBasePtr &other, const Ice::Current &=Ice::emptyCurrent) const override
Checks whether an object class is equal to another or if they contain an equal parent class.
Definition: PersistentObjectClassSegment.h:274
ImportExportComponent.h