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 
25 #include <vector>
26 
28 
31 #include <MemoryX/interface/core/EntityBase.h>
32 #include <MemoryX/interface/memorytypes/MemoryEntities.h>
33 #include <MemoryX/interface/memorytypes/MemorySegments.h>
34 
35 namespace memoryx
36 {
37  /**
38  * The persistent object class segment is a specialized segment of the SegmentedMemory.
39  * It keeps object classes which are held in prior knowledge (MongoDB) and thus are persistent.
40  * This segment is usually part of the prior knowledge memory.
41  */
43  virtual public PersistentEntitySegment,
44  virtual public PersistentObjectClassSegmentBase
45  {
46  public:
47  /**
48  * Creates a new peristent object class segment.
49  *
50  * @param entityCollection a proxy to the collection from commonstorage
51  * @param ic ice communicator
52  * @param useMongoIds whether to use entity IDs stored in MongoDB or internal ids
53  */
54  PersistentObjectClassSegment(CollectionInterfacePrx entityCollection,
56  bool useMongoIds = true) :
57  PersistentEntitySegment(entityCollection, ic, useMongoIds),
58  PersistentObjectClassSegmentBase()
59  {
60  }
61 
62  /**
63  * Retrieve a persistent object class by id
64  *
65  * @param id either mongoId (if useMongIds) or internal id
66  * @return pointer to object class on success
67  */
68  ObjectClassBasePtr
69  getObjectClassById(const ::std::string& id,
70  const ::Ice::Current& = Ice::emptyCurrent) const override
71  {
72  return ObjectClassBasePtr::dynamicCast(getEntityById(id));
73  }
74 
75  /**
76  * Retrieve a persistent object class by name
77  *
78  * @param name name of object class
79  * @return pointer to object class on success
80  */
81  ObjectClassBasePtr
82  getObjectClassByName(const ::std::string& name,
83  const ::Ice::Current& = Ice::emptyCurrent) const override
84  {
85  return ObjectClassBasePtr::dynamicCast(getEntityByName(name));
86  }
87 
88  /**
89  * @brief Retrieve a object class with all the parent classes,
90  * that means also the parent classes of the direct parent classes and so on.
91  * @param name Name of the object class to retrieve
92  * @return pointer to the object class
93  */
94  ObjectClassBasePtr
95  getObjectClassByNameWithAllParents(const ::std::string& name,
96  const ::Ice::Current& = Ice::emptyCurrent) const override
97  {
98  ObjectClassBasePtr objClass = ObjectClassBasePtr::dynamicCast(getEntityByName(name));
99 
100  if (!objClass)
101  {
102  ARMARX_ERROR_S << "No object class with name '" << name << "'";
103  return objClass;
104  }
105 
106  objClass->clearParentClasses();
107  ObjectClassList parents = getAllParentClasses(objClass->getName());
108 
109  if (objClass)
110  {
111  for (size_t i = 0; i < parents.size(); i++)
112  {
113  objClass->addParentClass(parents.at(i)->getName());
114  }
115  }
116 
117  return objClass;
118  }
119 
120  /**
121  * Retrieve child classes of a class
122  *
123  * @param parentClassName name of the parent
124  * @return list of child object classes
125  */
126  ObjectClassList
127  getChildClasses(const std::string& parentClassName,
128  const ::Ice::Current& = Ice::emptyCurrent) const override
129  {
130  ObjectClassList result;
131  EntityBaseList children = getEntitiesByAttrValue("parentClasses", parentClassName);
132 
133  for (EntityBaseList::const_iterator it = children.begin(); it != children.end(); ++it)
134  {
135  result.push_back(ObjectClassBasePtr::dynamicCast(*it));
136  }
137 
138  return result;
139  }
140 
141  /**
142  * Retrieve direct parent classes of a class
143  *
144  * @param parentClassName name of the parent
145  * @return list of child object classes
146  */
147  ObjectClassList
148  getParentClasses(const std::string& className,
149  const ::Ice::Current& = Ice::emptyCurrent) const override
150  {
151 
152  EntityBasePtr entity = getEntityByName(className);
153 
154  if (!entity)
155  {
156  throw armarx::LocalException("Could not find class with name ") << className;
157  }
158 
159  ObjectClassBasePtr objClass = ObjectClassBasePtr::dynamicCast(entity);
160 
161  if (!objClass)
162  {
163  throw armarx::LocalException("Could not cast class with name ") << className;
164  }
165 
166  NameList parentClassNameList = objClass->getParentClasses();
167  ObjectClassList parentClassList;
168 
169  for (NameList::const_iterator it = parentClassNameList.begin();
170  it != parentClassNameList.end();
171  ++it)
172  {
173  if (it->empty())
174  {
175  continue;
176  }
177 
178  ObjectClassBasePtr ptr = ObjectClassBasePtr::dynamicCast(getEntityByName(*it));
179 
180  if (!ptr)
181  {
182  ARMARX_INFO_S << "Could not cast parent " << *it << " of class " << className;
183  }
184  else
185  {
186  parentClassList.push_back(ptr);
187  }
188  }
189 
190  return parentClassList;
191  }
192 
193  /**
194  * Retrieve class and all subclasses. Retrieves a complete ontological subtree from the class prior knowledge.
195  *
196  * @param rootClassName name of the root class
197  * @return list of object classes in the subtree
198  */
199  ObjectClassList
200  getClassWithSubclasses(const std::string& rootClassName,
201  const ::Ice::Current& = Ice::emptyCurrent) const override
202  {
203  // iterate through classes
204  ObjectClassList relevantClasses;
205  ObjectClassPtr root = ObjectClassPtr::dynamicCast(getEntityByName(rootClassName));
206 
207  if (!root)
208  {
209  ARMARX_WARNING_S << "Parent Object Class '" << rootClassName
210  << "' does not exist in segment!";
211  return ObjectClassList();
212  }
213 
214  relevantClasses.push_back(root);
215 
216  int index = 0;
217 
218  while (index != int(relevantClasses.size()))
219  {
220  ObjectClassBasePtr current = relevantClasses.at(index);
221 
222  // add children of this class
223  ObjectClassList childs = getChildClasses(current->getName());
224 
225  if (childs.size() != 0)
226  {
227  std::copy(childs.begin(), childs.end(), std::back_inserter(relevantClasses));
228  }
229 
230  index++;
231  }
232 
233  unique(relevantClasses);
234 
235  return relevantClasses;
236  }
237 
238  /**
239  * @brief Retrieves recursively all parent classes for an object class from the database.
240  * @param className Name of object class for which the parents should be calculated.
241  * @return List of parent objects
242  */
243  ObjectClassList
244  getAllParentClasses(const std::string& className,
245  const ::Ice::Current& = Ice::emptyCurrent) const override
246  {
247  ObjectClassList relevantClasses, classesLeftToCheck;
248 
249  ObjectClassBasePtr current =
250  ObjectClassBasePtr::dynamicCast(getEntityByName(className));
251 
252  if (!current)
253  {
254  return relevantClasses;
255  }
256 
257  do
258  {
259  // add children of this class
260  if (!current)
261  {
262  throw armarx::LocalException("current is NULL!");
263  }
264 
265  // ARMARX_INFO_S << index << " Getting parents of " << current->getName();
266  ObjectClassList parents = getParentClasses(current->getName());
267 
268  if (parents.size() != 0)
269  {
270  std::copy(parents.begin(), parents.end(), std::back_inserter(relevantClasses));
271  std::copy(
272  parents.begin(), parents.end(), std::back_inserter(classesLeftToCheck));
273  }
274  unique(classesLeftToCheck);
275  if (classesLeftToCheck.size() == 0)
276  {
277  break;
278  }
279  current = *classesLeftToCheck.rbegin();
280  classesLeftToCheck.pop_back();
281  } while (true);
282 
283  unique(relevantClasses);
284  return relevantClasses;
285  }
286 
287  /**
288  * @brief Checks whether an object class is equal to another or if they contain an equal parent class
289  * @param objClass
290  * @param other
291  * @return
292  */
293  ObjectComparisonResult
294  compare(const ObjectClassBasePtr& objClass,
295  const ObjectClassBasePtr& other,
296  const Ice::Current& = Ice::emptyCurrent) const override
297  {
298  if (other->getName() == objClass->getName())
299  {
300  return eEqualClass;
301  }
302 
303  ObjectClassList otherParentClasses = getAllParentClasses(other->getName());
304  ObjectClassList parentClasses = getAllParentClasses(objClass->getName());
305 
306  // check parents names
307  for (ObjectClassList::iterator itOther = otherParentClasses.begin();
308  itOther != otherParentClasses.end();
309  itOther++)
310  {
311  if (objClass->getName() ==
312  (*itOther)->getName()) // other is a subclass of this -> so its equal
313  {
314  return eEqualClass;
315  }
316 
317  for (ObjectClassList::iterator it = parentClasses.begin();
318  it != parentClasses.end();
319  it++)
320  {
321  if ((*it)->getName() ==
322  (*itOther)
323  ->getName()) // parent of this is equal to parent of other, so only equal parent class
324  {
325  return eEqualParentClass;
326  }
327  }
328  }
329 
330  for (ObjectClassList::iterator it = parentClasses.begin(); it != parentClasses.end();
331  it++)
332  {
333  if ((*it)->getName() ==
334  other
335  ->getName()) // other is parent class of objClass -> so only equal parent class
336  {
337  return eEqualParentClass;
338  }
339  }
340 
341  return eNotEqualClass;
342  }
343 
344  bool
345  isParentClass(const ::std::string& className,
346  const ::std::string& parentCandidate,
347  const ::Ice::Current& = Ice::emptyCurrent) const override
348  {
349  ObjectClassList parentClasses = getAllParentClasses(className);
350 
351  for (const auto& parent : parentClasses)
352  {
353  if (parent->getName() == parentCandidate)
354  {
355  return true;
356  }
357  }
358 
359  return false;
360  }
361 
362  static void
363  unique(ObjectClassList& classes)
364  {
365  auto objectClassPtrCompareLess =
366  [](const ObjectClassBasePtr& lhs, const ObjectClassBasePtr& rhs)
367  { return lhs->getName() < rhs->getName(); };
368  auto objectClassPtrCompareEq =
369  [](const ObjectClassBasePtr& lhs, const ObjectClassBasePtr& rhs)
370  { return lhs->getName() == rhs->getName(); };
371  std::sort(classes.begin(), classes.end(), objectClassPtrCompareLess);
372  auto newEnd = std::unique(classes.begin(), classes.end(), objectClassPtrCompareEq);
373  classes.erase(newEnd, classes.end());
374  }
375  };
376 
378 
379 } // namespace memoryx
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:69
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:54
memoryx::PersistentObjectClassSegment
The persistent object class segment is a specialized segment of the SegmentedMemory.
Definition: PersistentObjectClassSegment.h:42
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:127
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:95
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:200
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:216
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:82
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:213
memoryx::PersistentObjectClassSegment::unique
static void unique(ObjectClassList &classes)
Definition: PersistentObjectClassSegment.h:363
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:148
memoryx::PersistentObjectClassSegment::isParentClass
bool isParentClass(const ::std::string &className, const ::std::string &parentCandidate, const ::Ice::Current &=Ice::emptyCurrent) const override
Definition: PersistentObjectClassSegment.h:345
memoryx::PersistentEntitySegment
The PersistentEntitySegment class is the base class for all memory segments containing memoryx::Entit...
Definition: PersistentEntitySegment.h:105
ARMARX_INFO_S
#define ARMARX_INFO_S
Definition: Logging.h:202
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:244
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:294
ImportExportComponent.h