AbstractObjectSerializer.cpp
Go to the documentation of this file.
1/*
2* This file is part of ArmarX.
3*
4* Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5*
6* ArmarX is free software; you can redistribute it and/or modify
7* it under the terms of the GNU General Public License version 2 as
8* published by the Free Software Foundation.
9*
10* ArmarX is distributed in the hope that it will be useful, but
11* WITHOUT ANY WARRANTY; without even the implied warranty of
12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13* GNU General Public License for more details.
14*
15* You should have received a copy of the GNU General Public License
16* along with this program. If not, see <http://www.gnu.org/licenses/>.
17*
18* @package ArmarX::Core
19* @author ALexey Kozlov ( kozlov at kit dot edu)
20* @date 11.09.2012
21* @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22* GNU General Public License
23*/
24
25
27
28#include <Ice/LocalException.h>
29#include <Ice/ValueFactory.h>
30#include <IceUtil/UUID.h>
31
35
36namespace armarx
37{
41
46
50
51 void
56
59 {
61
62 const VariantTypeId type = val->getType();
63
64 try
65 {
66 variantNode->setString("typeName", Variant::typeToString(type));
67 }
68 // catch in case typeToString fails
69 catch (...)
70 {
71 variantNode->setInt("type", type);
72 }
73
74 if (val->ice_id() == TimedVariantBase::ice_staticId())
75 {
76 TimedVariantPtr tvar = TimedVariantPtr::dynamicCast(val);
77 variantNode->setDouble("timestamp", tvar->getTimestamp());
78 }
79
80 if (!val->getInitialized())
81 {
82 variantNode->setString("value", "(not initialized)");
83 }
84 else if (type == VariantType::Invalid)
85 {
86 variantNode->setString("value", "(invalid type)");
87 }
88 else if (type == VariantType::Int)
89 {
90 variantNode->setInt("value", val->getInt());
91 }
92 else if (type == VariantType::Long)
93 {
94 variantNode->setInt("value", static_cast<int>(val->getLong()));
95 }
96 else if (type == VariantType::Float)
97 {
98 variantNode->setFloat("value", val->getFloat());
99 }
100 else if (type == VariantType::Double)
101 {
102 variantNode->setDouble("value", val->getDouble());
103 }
104 else if (type == VariantType::String)
105 {
106 variantNode->setString("value", val->getString());
107 }
108 else if (type == VariantType::Bool)
109 {
110 variantNode->setBool("value", val->getBool());
111 }
112 else
113 {
114 VariantDataClassPtr ptr = val->getClass<VariantDataClass>();
115
116 if (ptr)
117 {
118 const AbstractObjectSerializerPtr valueNode = createElement();
119 ptr->serialize(valueNode);
120
121 variantNode->setElement("value", valueNode);
122 }
123 else
124 {
125 variantNode->setString("value", "(NULLCAST for" + val->getTypeName() + ")");
126 }
127 }
128
129 return variantNode;
130 }
131
134 {
135 // get the type
136 VariantTypeId type;
137
138 if (hasElement("typeName"))
139 {
140 std::string typeName = getString("typeName");
141 type = Variant::hashTypeName(typeName);
142 // make sure the variant type is registered with the variant type map, later only the int is known and would not be able to transform this back for prettier error messages
143 if (Variant::getTypes().count(type) == 0)
144 {
145 Variant::addTypeName(typeName);
146 }
147 }
148 else
149 {
150 type = getInt("type");
151 }
152
153 // create empty variant with "invalid" type
154 // ugly switch case to distinct between timed variant and normal - doing it nicely would require big restructuring
155 VariantPtr var;
156 if (hasElement("timestamp"))
157 {
158 TimedVariantPtr tvar =
159 new TimedVariant(Variant(), IceUtil::Time::microSeconds(getDouble("timestamp")));
160 var = tvar;
161 }
162 else
163 {
164 var = new Variant();
165 }
166
167 // init variant with type and value specified in JSON/XML/... node
168 // process basic types first
169 if (type == VariantType::Bool)
170 {
171 var->setBool(getBool("value"));
172 }
173 else if (type == VariantType::String)
174 {
175 var->setString(getString("value"));
176 }
177 else if (type == VariantType::Float)
178 {
179 var->setFloat(getFloat("value"));
180 }
181 else if (type == VariantType::Double)
182 {
183 var->setDouble(getDouble("value"));
184 }
185 else if (type == VariantType::Int)
186 {
187 var->setInt(getInt("value"));
188 }
189 else if (type == VariantType::Long)
190 {
191 var->setLong(getInt("value"));
192 }
193 else // must be VariantDataClass
194 {
195 // for complex types, we need to use Ice object factory to create an instance of object by its class name
196 std::string typeStr = Variant::typeToString(type);
197 VariantDataClassPtr data;
198
199 if (ic)
200 {
201 Ice::ValueFactoryPtr valFac = ic->getValueFactoryManager()->find(typeStr);
202
203 if (!valFac)
204 {
205 throw Ice::NoValueFactoryException(__FILE__,
206 __LINE__,
207 "Could not find ValueFactory for string '" +
208 typeStr + "'",
209 typeStr);
210 }
211
212 data = VariantDataClassPtr::dynamicCast(valFac->create(typeStr));
213 }
214 else
215 {
216 ARMARX_WARNING_S << "Could not deserialize variant parameter, because "
217 "IceCommunicator wasn't set in Serializer";
218 return VariantPtr();
219 }
220
221 //VariantDataClass data = var->getClass< armarx::VariantDataClass >();
222 static Ice::Current c;
223
224 if (!c.adapter)
225 {
226 c.adapter = ic->createObjectAdapterWithEndpoints(
227 "Dummy" + IceUtil::generateUUID(),
228 "tcp"); // pass adapter to deserialize() so that a proxy can be retrieved in the variant
229 }
230
231 data->deserialize(getElement("value"), c);
232 var->setClass(data);
233 }
234
235 return var;
236 }
237
238 void
239 AbstractObjectSerializer::setVariant(const ::std::string& key, const VariantPtr& val)
240 {
241 const AbstractObjectSerializerPtr variantNode = serializeVariant(val);
242
243 setElement(key, variantNode);
244 }
245
246 void
248 {
249 const AbstractObjectSerializerPtr variantNode = serializeVariant(val);
250
251 setElement(index, variantNode);
252 }
253
255 AbstractObjectSerializer::getVariant(const ::std::string& key) const
256 {
257 // variants are stored as object nodes, e.g. in JSON myVariant: { type: <type hash>, value: 1.0 }
258 // so first get the node with specified key
259 AbstractObjectSerializerPtr variantNode = getElement(key);
260
261 return variantNode->deserializeVariant();
262 }
263
266 {
267 // variants are stored as object nodes, e.g. in JSON myVariant: { type: <type hash>, value: 1.0 }
268 // so first get the node with specified key
270
271 return variantNode->deserializeVariant();
272 }
273
274 SerializablePtr
275 AbstractObjectSerializer::getIceObject(const ::std::string& key) const
276 {
277 AbstractObjectSerializerPtr iceObjectNode = getElement(key);
278 return iceObjectNode ? iceObjectNode->deserializeIceObject() : SerializablePtr();
279 }
280
281 SerializablePtr
283 {
285 return iceObjectNode ? iceObjectNode->deserializeIceObject() : SerializablePtr();
286 }
287
288 void
289 AbstractObjectSerializer::setIceObject(const ::std::string& key, const SerializablePtr& obj)
290 {
291 const AbstractObjectSerializerPtr iceObjectNode = createElement();
292 iceObjectNode->serializeIceObject(obj);
293
294 setElement(key, iceObjectNode);
295 }
296
297 void
298 AbstractObjectSerializer::setIceObject(unsigned int index, const SerializablePtr& obj)
299 {
300 const AbstractObjectSerializerPtr iceObjectNode = createElement();
301 iceObjectNode->serializeIceObject(obj);
302
303 setElement(index, iceObjectNode);
304 }
305
306 void
308 {
309 reset();
310 setString("type", obj->ice_id());
311 obj->serialize(this);
312 }
313
314 SerializablePtr
316 {
317 const std::string typeStr = getString("type");
318
319 if (ic)
320 {
321 Ice::ValueFactoryPtr valFac = ic->getValueFactoryManager()->find(typeStr);
322
323 if (!valFac)
324 {
326 "Could not find ObjectFactory for string '" + typeStr + "'");
327 }
328
329 SerializablePtr obj = SerializablePtr::dynamicCast(valFac->create(typeStr));
330 static Ice::Current c;
331
332 if (!c.adapter)
333 {
334 c.adapter = ic->createObjectAdapterWithEndpoints(
335 "Dummy" + IceUtil::generateUUID(),
336 "tcp"); // pass adapter to deserialize() so that a proxy can be retrieved in the variant
337 }
338
339 obj->deserialize(this, c);
340 return obj;
341 }
342 else
343 {
344 // ARMARX_LOG << eWARNING << "could not deserialize IceObject cause IceCommunicator wasn't set in Serializer" << flush;
345 return SerializablePtr();
346 }
347 }
348} // namespace armarx
uint8_t index
constexpr T c
virtual float getFloat(const ::std::string &key) const =0
virtual int getInt(const ::std::string &key) const =0
virtual bool getBool(const ::std::string &key) const =0
virtual void setIceObject(const ::std::string &key, const SerializablePtr &val)
virtual AbstractObjectSerializerPtr createElement() const =0
virtual SerializablePtr getIceObject(const ::std::string &key) const
void setIceCommunicator(Ice::CommunicatorPtr ic)
void serializeIceObject(const SerializablePtr &obj)
virtual void setElement(const ::std::string &key, const AbstractObjectSerializerPtr &val)=0
virtual VariantPtr getVariant(const ::std::string &key) const
virtual AbstractObjectSerializerPtr getElement(unsigned int index) const =0
virtual void setString(const ::std::string &key, const std::string &val)=0
AbstractObjectSerializerPtr serializeVariant(const VariantPtr &val) const
virtual bool hasElement(const ::std::string &key) const =0
virtual void setVariant(const ::std::string &key, const VariantPtr &val)
virtual std::string getString(const ::std::string &key) const =0
virtual double getDouble(const ::std::string &key) const =0
The Variant class is described here: Variants.
Definition Variant.h:224
static const std::map< VariantTypeId, std::string > & getTypes()
Returns the mapping of currently registered types.
Definition Variant.cpp:863
static VariantTypeId addTypeName(const std::string &typeName)
Register a new type for the use in a Variant.
Definition Variant.cpp:869
static int hashTypeName(const std::string &typeName)
Compute and return a hash value for a given type name.
Definition Variant.cpp:813
static std::string typeToString(VariantTypeId typeId)
Return the name of the registered type typeId.
Definition Variant.cpp:848
#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
const VariantTypeId String
Definition Variant.h:921
const VariantTypeId Invalid
Definition Variant.h:915
const VariantTypeId Int
Definition Variant.h:917
const VariantTypeId Long
Definition Variant.h:918
const VariantTypeId Bool
Definition Variant.h:916
const VariantTypeId Double
Definition Variant.h:920
const VariantTypeId Float
Definition Variant.h:919
This file offers overloads of toIce() and fromIce() functions for STL container types.
IceInternal::Handle< TimedVariant > TimedVariantPtr
IceInternal::Handle< Variant > VariantPtr
Definition Variant.h:41
IceInternal::Handle< AbstractObjectSerializer > AbstractObjectSerializerPtr
Ice::Int VariantTypeId
Definition Variant.h:43