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
35namespace 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
uint8_t index
#define ARMARXCOMPONENT_IMPORT_EXPORT
PersistentEntitySegment(CollectionInterfacePrx entityCollection, Ice::CommunicatorPtr ic, bool useMongoIds=true)
EntityBasePtr getEntityById(const ::std::string &entityId, const ::Ice::Current &=Ice::emptyCurrent) const override
EntityBaseList getEntitiesByAttrValue(const ::std::string &attrName, const ::std::string &attrValue, const ::Ice::Current &=Ice::emptyCurrent) const override
EntityBasePtr getEntityByName(const ::std::string &name, const ::Ice::Current &=Ice::emptyCurrent) const override
ObjectClassBasePtr getObjectClassById(const ::std::string &id, const ::Ice::Current &=Ice::emptyCurrent) const override
Retrieve a persistent object class by id.
ObjectClassList getParentClasses(const std::string &className, const ::Ice::Current &=Ice::emptyCurrent) const override
Retrieve direct parent classes of a class.
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...
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.
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.
static void unique(ObjectClassList &classes)
bool isParentClass(const ::std::string &className, const ::std::string &parentCandidate, const ::Ice::Current &=Ice::emptyCurrent) const override
ObjectClassBasePtr getObjectClassByName(const ::std::string &name, const ::Ice::Current &=Ice::emptyCurrent) const override
Retrieve a persistent object class by name.
ObjectClassList getClassWithSubclasses(const std::string &rootClassName, const ::Ice::Current &=Ice::emptyCurrent) const override
Retrieve class and all subclasses.
ObjectClassList getChildClasses(const std::string &parentClassName, const ::Ice::Current &=Ice::emptyCurrent) const override
Retrieve child classes of a class.
PersistentObjectClassSegment(CollectionInterfacePrx entityCollection, Ice::CommunicatorPtr ic, bool useMongoIds=true)
Creates a new peristent object class segment.
#define ARMARX_ERROR_S
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:216
#define ARMARX_INFO_S
Definition Logging.h:202
#define ARMARX_WARNING_S
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:213
::IceInternal::Handle<::Ice::Communicator > CommunicatorPtr
Definition IceManager.h:49
VirtualRobot headers.
IceInternal::Handle< PersistentObjectClassSegment > PersistentObjectClassSegmentPtr
IceInternal::Handle< ObjectClass > ObjectClassPtr
Definition ObjectClass.h:35