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 
31 
32 #include <IceUtil/UUID.h>
33 #include <Ice/LocalException.h>
34 #include <Ice/ValueFactory.h>
35 
36 
37 namespace armarx
38 {
40  idField("id")
41  {
42  }
43 
45  ic(ic),
46  idField("id")
47  {
48  }
49 
51  {
52  }
53 
55  {
56  this->ic = ic;
57  }
58 
60  {
62 
63  const VariantTypeId type = val->getType();
64 
65  try
66  {
67  variantNode->setString("typeName", Variant::typeToString(type));
68  }
69  // catch in case typeToString fails
70  catch (...)
71  {
72  variantNode->setInt("type", type);
73  }
74 
75  if (val->ice_id() == TimedVariantBase::ice_staticId())
76  {
77  TimedVariantPtr tvar = TimedVariantPtr::dynamicCast(val);
78  variantNode->setDouble("timestamp", tvar->getTimestamp());
79  }
80 
81  if (!val->getInitialized())
82  {
83  variantNode->setString("value", "(not initialized)");
84  }
85  else if (type == VariantType::Invalid)
86  {
87  variantNode->setString("value", "(invalid type)");
88  }
89  else if (type == VariantType::Int)
90  {
91  variantNode->setInt("value", val->getInt());
92  }
93  else if (type == VariantType::Long)
94  {
95  variantNode->setInt("value", static_cast<int>(val->getLong()));
96  }
97  else if (type == VariantType::Float)
98  {
99  variantNode->setFloat("value", val->getFloat());
100  }
101  else if (type == VariantType::Double)
102  {
103  variantNode->setDouble("value", val->getDouble());
104  }
105  else if (type == VariantType::String)
106  {
107  variantNode->setString("value", val->getString());
108  }
109  else if (type == VariantType::Bool)
110  {
111  variantNode->setBool("value", val->getBool());
112  }
113  else
114  {
115  VariantDataClassPtr ptr = val->getClass<VariantDataClass>();
116 
117  if (ptr)
118  {
119  const AbstractObjectSerializerPtr valueNode = createElement();
120  ptr->serialize(valueNode);
121 
122  variantNode->setElement("value", valueNode);
123  }
124  else
125  {
126  variantNode->setString("value", "(NULLCAST for" + val->getTypeName() + ")");
127  }
128  }
129 
130  return variantNode;
131  }
132 
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 = new TimedVariant(Variant(), IceUtil::Time::microSeconds(getDouble("timestamp")));
159  var = tvar;
160  }
161  else
162  {
163  var = new Variant();
164  }
165 
166  // init variant with type and value specified in JSON/XML/... node
167  // process basic types first
168  if (type == VariantType::Bool)
169  {
170  var->setBool(getBool("value"));
171  }
172  else if (type == VariantType::String)
173  {
174  var->setString(getString("value"));
175  }
176  else if (type == VariantType::Float)
177  {
178  var->setFloat(getFloat("value"));
179  }
180  else if (type == VariantType::Double)
181  {
182  var->setDouble(getDouble("value"));
183  }
184  else if (type == VariantType::Int)
185  {
186  var->setInt(getInt("value"));
187  }
188  else if (type == VariantType::Long)
189  {
190  var->setLong(getInt("value"));
191  }
192  else // must be VariantDataClass
193  {
194  // for complex types, we need to use Ice object factory to create an instance of object by its class name
195  std::string typeStr = Variant::typeToString(type);
196  VariantDataClassPtr data;
197 
198  if (ic)
199  {
200  Ice::ValueFactoryPtr valFac = ic->getValueFactoryManager()->find(typeStr);
201 
202  if (!valFac)
203  {
204  throw Ice::NoValueFactoryException(__FILE__, __LINE__, "Could not find ValueFactory for string '" + typeStr + "'", typeStr);
205  }
206 
207  data = VariantDataClassPtr::dynamicCast(valFac->create(typeStr));
208  }
209  else
210  {
211  ARMARX_WARNING_S << "Could not deserialize variant parameter, because IceCommunicator wasn't set in Serializer";
212  return VariantPtr();
213  }
214 
215  //VariantDataClass data = var->getClass< armarx::VariantDataClass >();
216  static Ice::Current c;
217 
218  if (!c.adapter)
219  {
220  c.adapter = ic->createObjectAdapterWithEndpoints("Dummy" + IceUtil::generateUUID(), "tcp"); // pass adapter to deserialize() so that a proxy can be retrieved in the variant
221  }
222 
223  data->deserialize(getElement("value"), c);
224  var->setClass(data);
225  }
226 
227  return var;
228  }
229 
230  void AbstractObjectSerializer::setVariant(const ::std::string& key, const VariantPtr& val)
231  {
232  const AbstractObjectSerializerPtr variantNode = serializeVariant(val);
233 
234  setElement(key, variantNode);
235  }
236 
238  {
239  const AbstractObjectSerializerPtr variantNode = serializeVariant(val);
240 
241  setElement(index, variantNode);
242  }
243 
244  VariantPtr AbstractObjectSerializer::getVariant(const ::std::string& key) const
245  {
246  // variants are stored as object nodes, e.g. in JSON myVariant: { type: <type hash>, value: 1.0 }
247  // so first get the node with specified key
248  AbstractObjectSerializerPtr variantNode = getElement(key);
249 
250  return variantNode->deserializeVariant();
251  }
252 
254  {
255  // variants are stored as object nodes, e.g. in JSON myVariant: { type: <type hash>, value: 1.0 }
256  // so first get the node with specified key
258 
259  return variantNode->deserializeVariant();
260  }
261 
262  SerializablePtr AbstractObjectSerializer::getIceObject(const ::std::string& key) const
263  {
264  AbstractObjectSerializerPtr iceObjectNode = getElement(key);
265  return iceObjectNode ? iceObjectNode->deserializeIceObject() : SerializablePtr();
266  }
267 
269  {
271  return iceObjectNode ? iceObjectNode->deserializeIceObject() : SerializablePtr();
272  }
273 
274  void AbstractObjectSerializer::setIceObject(const ::std::string& key, const SerializablePtr& obj)
275  {
276  const AbstractObjectSerializerPtr iceObjectNode = createElement();
277  iceObjectNode->serializeIceObject(obj);
278 
279  setElement(key, iceObjectNode);
280  }
281 
282  void AbstractObjectSerializer::setIceObject(unsigned int index, const SerializablePtr& obj)
283  {
284  const AbstractObjectSerializerPtr iceObjectNode = createElement();
285  iceObjectNode->serializeIceObject(obj);
286 
287  setElement(index, iceObjectNode);
288  }
289 
290  void AbstractObjectSerializer::serializeIceObject(const SerializablePtr& obj)
291  {
292  reset();
293  setString("type", obj->ice_id());
294  obj->serialize(this);
295  }
296 
298  {
299  const std::string typeStr = getString("type");
300 
301  if (ic)
302  {
303  Ice::ValueFactoryPtr valFac = ic->getValueFactoryManager()->find(typeStr);
304 
305  if (!valFac)
306  {
307  throw exceptions::local::eNullPointerException("Could not find ObjectFactory for string '" + typeStr + "'");
308  }
309 
310  SerializablePtr obj = SerializablePtr::dynamicCast(valFac->create(typeStr));
311  static Ice::Current c;
312 
313  if (!c.adapter)
314  {
315  c.adapter = ic->createObjectAdapterWithEndpoints("Dummy" + IceUtil::generateUUID(), "tcp"); // pass adapter to deserialize() so that a proxy can be retrieved in the variant
316  }
317 
318  obj->deserialize(this, c);
319  return obj;
320  }
321  else
322  {
323  // ARMARX_LOG << eWARNING << "could not deserialize IceObject cause IceCommunicator wasn't set in Serializer" << flush;
324  return SerializablePtr();
325  }
326  }
327 }
armarx::AbstractObjectSerializer::createElement
virtual AbstractObjectSerializerPtr createElement() const =0
armarx::Variant
The Variant class is described here: Variants.
Definition: Variant.h:224
armarx::AbstractObjectSerializer::getIceObject
virtual SerializablePtr getIceObject(const ::std::string &key) const
Definition: AbstractObjectSerializer.cpp:262
cyberglove_with_calib_22dof.ic
ic
Definition: cyberglove_with_calib_22dof.py:22
armarx::VariantType::Float
const VariantTypeId Float
Definition: Variant.h:918
index
uint8_t index
Definition: EtherCATFrame.h:59
armarx::AbstractObjectSerializer::setIceCommunicator
void setIceCommunicator(Ice::CommunicatorPtr ic)
Definition: AbstractObjectSerializer.cpp:54
armarx::AbstractObjectSerializer::setVariant
virtual void setVariant(const ::std::string &key, const VariantPtr &val)
Definition: AbstractObjectSerializer.cpp:230
AbstractObjectSerializer.h
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
armarx::Variant::getTypes
static const std::map< VariantTypeId, std::string > & getTypes()
Returns the mapping of currently registered types.
Definition: Variant.cpp:746
armarx::VariantType::Bool
const VariantTypeId Bool
Definition: Variant.h:915
armarx::exceptions::local::eNullPointerException
Definition: Exception.h:42
armarx::AbstractObjectSerializer::getVariant
virtual VariantPtr getVariant(const ::std::string &key) const
Definition: AbstractObjectSerializer.cpp:244
armarx::AbstractObjectSerializer::serializeVariant
AbstractObjectSerializerPtr serializeVariant(const VariantPtr &val) const
Definition: AbstractObjectSerializer.cpp:59
IceInternal::Handle< ::Ice::Communicator >
armarx::VariantType::Double
const VariantTypeId Double
Definition: Variant.h:919
armarx::VariantPtr
IceInternal::Handle< Variant > VariantPtr
Definition: Variant.h:42
armarx::AbstractObjectSerializer::getElement
virtual AbstractObjectSerializerPtr getElement(unsigned int index) const =0
armarx::VariantType::Invalid
const VariantTypeId Invalid
Definition: Variant.h:914
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:297
armarx::AbstractObjectSerializer::~AbstractObjectSerializer
~AbstractObjectSerializer() override
Definition: AbstractObjectSerializer.cpp:50
armarx::Variant::typeToString
static std::string typeToString(VariantTypeId typeId)
Return the name of the registered type typeId.
Definition: Variant.cpp:732
armarx::VariantType::Long
const VariantTypeId Long
Definition: Variant.h:917
armarx::AbstractObjectSerializer::getFloat
virtual float getFloat(const ::std::string &key) const =0
armarx::AbstractObjectSerializer::serializeIceObject
void serializeIceObject(const SerializablePtr &obj)
Definition: AbstractObjectSerializer.cpp:290
armarx::VariantTypeId
Ice::Int VariantTypeId
Definition: Variant.h:44
armarx::AbstractObjectSerializer::AbstractObjectSerializer
AbstractObjectSerializer()
Definition: AbstractObjectSerializer.cpp:39
armarx::AbstractObjectSerializer::ic
Ice::CommunicatorPtr ic
Definition: AbstractObjectSerializer.h:166
ARMARX_WARNING_S
#define ARMARX_WARNING_S
Definition: Logging.h:206
armarx::AbstractObjectSerializer::setIceObject
virtual void setIceObject(const ::std::string &key, const SerializablePtr &val)
Definition: AbstractObjectSerializer.cpp:274
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:916
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:699
Logging.h
Exception.h
armarx::VariantType::String
const VariantTypeId String
Definition: Variant.h:920
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:28
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:751
armarx::TimedVariant
Definition: TimedVariant.h:40