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 
36 namespace armarx
37 {
39  {
40  }
41 
43  ic(ic), idField("id")
44  {
45  }
46 
48  {
49  }
50 
51  void
53  {
54  this->ic = ic;
55  }
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 
132  VariantPtr
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 
254  VariantPtr
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 
264  VariantPtr
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
armarx::AbstractObjectSerializer::createElement
virtual AbstractObjectSerializerPtr createElement() const =0
armarx::Variant
The Variant class is described here: Variants.
Definition: Variant.h:223
armarx::AbstractObjectSerializer::getIceObject
virtual SerializablePtr getIceObject(const ::std::string &key) const
Definition: AbstractObjectSerializer.cpp:275
cyberglove_with_calib_22dof.ic
ic
Definition: cyberglove_with_calib_22dof.py:22
armarx::VariantType::Float
const VariantTypeId Float
Definition: Variant.h:919
index
uint8_t index
Definition: EtherCATFrame.h:59
armarx::AbstractObjectSerializer::setIceCommunicator
void setIceCommunicator(Ice::CommunicatorPtr ic)
Definition: AbstractObjectSerializer.cpp:52
armarx::AbstractObjectSerializer::setVariant
virtual void setVariant(const ::std::string &key, const VariantPtr &val)
Definition: AbstractObjectSerializer.cpp:239
AbstractObjectSerializer.h
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:46
armarx::Variant::getTypes
static const std::map< VariantTypeId, std::string > & getTypes()
Returns the mapping of currently registered types.
Definition: Variant.cpp:863
armarx::VariantType::Bool
const VariantTypeId Bool
Definition: Variant.h:916
armarx::exceptions::local::eNullPointerException
Definition: Exception.h:49
armarx::AbstractObjectSerializer::getVariant
virtual VariantPtr getVariant(const ::std::string &key) const
Definition: AbstractObjectSerializer.cpp:255
armarx::AbstractObjectSerializer::serializeVariant
AbstractObjectSerializerPtr serializeVariant(const VariantPtr &val) const
Definition: AbstractObjectSerializer.cpp:58
IceInternal::Handle<::Ice::Communicator >
armarx::VariantType::Double
const VariantTypeId Double
Definition: Variant.h:920
armarx::VariantPtr
IceInternal::Handle< Variant > VariantPtr
Definition: Variant.h:41
armarx::AbstractObjectSerializer::getElement
virtual AbstractObjectSerializerPtr getElement(unsigned int index) const =0
armarx::VariantType::Invalid
const VariantTypeId Invalid
Definition: Variant.h:915
data
uint8_t data[1]
Definition: EtherCATFrame.h:68
armarx::AbstractObjectSerializer::deserializeVariant
VariantPtr deserializeVariant()
Definition: AbstractObjectSerializer.cpp:133
armarx::AbstractObjectSerializer::deserializeIceObject
SerializablePtr deserializeIceObject()
Definition: AbstractObjectSerializer.cpp:315
armarx::AbstractObjectSerializer::~AbstractObjectSerializer
~AbstractObjectSerializer() override
Definition: AbstractObjectSerializer.cpp:47
armarx::Variant::typeToString
static std::string typeToString(VariantTypeId typeId)
Return the name of the registered type typeId.
Definition: Variant.cpp:848
armarx::VariantType::Long
const VariantTypeId Long
Definition: Variant.h:918
armarx::AbstractObjectSerializer::getFloat
virtual float getFloat(const ::std::string &key) const =0
armarx::AbstractObjectSerializer::serializeIceObject
void serializeIceObject(const SerializablePtr &obj)
Definition: AbstractObjectSerializer.cpp:307
armarx::VariantTypeId
Ice::Int VariantTypeId
Definition: Variant.h:43
armarx::AbstractObjectSerializer::AbstractObjectSerializer
AbstractObjectSerializer()
Definition: AbstractObjectSerializer.cpp:38
armarx::AbstractObjectSerializer::ic
Ice::CommunicatorPtr ic
Definition: AbstractObjectSerializer.h:178
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:213
armarx::AbstractObjectSerializer::setIceObject
virtual void setIceObject(const ::std::string &key, const SerializablePtr &val)
Definition: AbstractObjectSerializer.cpp:289
TimedVariant.h
armarx::AbstractObjectSerializer::getBool
virtual bool getBool(const ::std::string &key) const =0
armarx::AbstractObjectSerializer::getInt
virtual int getInt(const ::std::string &key) const =0
armarx::AbstractObjectSerializer::hasElement
virtual bool hasElement(const ::std::string &key) const =0
armarx::AbstractObjectSerializer::getString
virtual std::string getString(const ::std::string &key) const =0
armarx::VariantType::Int
const VariantTypeId Int
Definition: Variant.h:917
armarx::AbstractObjectSerializer::setElement
virtual void setElement(const ::std::string &key, const AbstractObjectSerializerPtr &val)=0
armarx::Variant::hashTypeName
static int hashTypeName(const std::string &typeName)
Compute and return a hash value for a given type name.
Definition: Variant.cpp:813
Logging.h
Exception.h
armarx::VariantType::String
const VariantTypeId String
Definition: Variant.h:921
armarx::AbstractObjectSerializer::getDouble
virtual double getDouble(const ::std::string &key) const =0
armarx::AbstractObjectSerializer::reset
virtual void reset()=0
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::AbstractObjectSerializer::setString
virtual void setString(const ::std::string &key, const std::string &val)=0
armarx::Variant::addTypeName
static VariantTypeId addTypeName(const std::string &typeName)
Register a new type for the use in a Variant.
Definition: Variant.cpp:869
armarx::TimedVariant
Definition: TimedVariant.h:39