JSONObject.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 2012
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24 
25 #include "JSONObject.h"
26 
29 
30 #include <SimoxUtility/algorithm/string/string_tools.h>
31 
32 namespace armarx
33 {
36  {
37  setElementType(elemType);
38  }
39 
42  {
44  }
45 
47  IceUtil::Shared(toCopy),
49  {
51  setIdField(toCopy.getIdField());
52  }
53 
55  {
56  }
57 
58  std::string JSONObject::toString(const ::Ice::Current&) const
59  {
60  return asString(false);
61  }
62 
63  std::string JSONObject::asString(bool pretty /* = false */) const
64  {
65  if (pretty)
66  {
67  return jsonValue.toStyledString();
68  }
69  else
70  {
71  Json::FastWriter writer;
72  // writer.enableYAMLCompatibility();
73  std::string jsonString = writer.write(jsonValue);
74 
75  // remove newline which is appended by jsoncpp
76  // MongoDB seems to have issues with it
77  while (jsonString.at(jsonString.size() - 1) == '\n')
78  {
79  jsonString.erase(jsonString.end() - 1);
80  }
81 
82  return jsonString;
83  }
84  }
85 
86  void JSONObject::fromString(const ::std::string& jsonString, const ::Ice::Current&)
87  {
89  Json::Reader reader;
90  reader.parse(jsonString, jsonValue);
91  }
92 
94  {
95  return jsonValue;
96  }
97 
99  {
101  }
102 
103 
104  void JSONObject::setElement(const ::std::string& key, const armarx::AbstractObjectSerializerPtr& obj)
105  {
106  const JSONObjectPtr jsonObj = JSONObjectPtr::dynamicCast(obj);
107  jsonValue[key] = jsonObj->jsonValue;
108  }
109 
110  void JSONObject::setVariantArray(const std::string& key, const std::vector<VariantBasePtr>& val)
111  {
112  Json::Value arr(Json::arrayValue);
113 
114  if (val.size() > 0)
115  {
116  arr.resize(val.size());
117 
118  for (size_t i = 0; i < val.size(); ++i)
119  {
120  VariantPtr var = VariantPtr::dynamicCast(val.at(i));
122  const JSONObjectPtr jsonObj = JSONObjectPtr::dynamicCast(serial);
123  arr[int(i)] = jsonObj->jsonValue;
124  }
125  }
126 
127  jsonValue[key] = arr;
128  }
129 
130  void JSONObject::setVariantArray(const std::string& key, const std::vector<VariantPtr>& val)
131  {
132  std::vector<VariantBasePtr> baseList;
133  baseList.resize(val.size());
134 
135  for (unsigned int i = 0; i < val.size(); i++)
136  {
137  baseList.at(i) = val.at(i);
138  }
139 
140  setVariantArray(key, baseList);
141  }
142 
143  void JSONObject::setVariantMap(const std::string& key, const StringVariantBaseMap& val)
144  {
145  Json::Value arr(Json::arrayValue);
146 
147  if (val.size() > 0)
148  {
149  arr.resize(val.size());
150  size_t i = 0;
151 
152  for (StringVariantBaseMap::const_iterator it = val.begin(); it != val.end(); ++it, i++)
153  {
154  VariantPtr var = VariantPtr::dynamicCast(it->second);
155  JSONObject json(ic);
156  json.setString("key", it->first);
157  json.setVariant("variant", var);
158  arr[int(i)] = json.jsonValue;
159  }
160  }
161 
162  jsonValue[key] = arr;
163  }
164 
166  {
167  const JSONObjectPtr jsonObj = JSONObjectPtr::dynamicCast(obj);
168  jsonValue[index] = jsonObj->jsonValue;
169  }
170 
172  {
173  const JSONObjectPtr jsonObj = JSONObjectPtr::dynamicCast(obj);
174 
175  if (jsonValue.isArray())
176  {
177  jsonValue.append(jsonObj->jsonValue);
178  }
179  else
180  {
181  throw JSONInvalidDataTypeException();
182  }
183  }
184 
186  {
188  {
189  const std::vector<std::string> elemNames = obj->getElementNames();
190 
191  for (std::vector<std::string>::const_iterator it = elemNames.begin(); it != elemNames.end(); ++it)
192  {
193  set(*it, obj->getElement(*it));
194  }
195  }
196  else
197  {
198  throw JSONInvalidDataTypeException();
199  }
200  }
201 
202  unsigned int JSONObject::size() const
203  {
204  return jsonValue.size();
205  }
206 
207  bool JSONObject::hasElement(const ::std::string& key) const
208  {
209  return jsonValue.isMember(key);
210  }
211 
212  void JSONObject::get(const Json::Value& val, bool& result) const
213  {
214  if (!val.isBool())
215  {
216  throw JSONInvalidDataTypeException();
217  }
218  else
219  {
220  result = val.asBool();
221  }
222  }
223 
224  void JSONObject::get(const Json::Value& val, int& result) const
225  {
226  if (!val.isIntegral())
227  {
228  throw JSONInvalidDataTypeException();
229  }
230  else
231  {
232  result = val.asInt();
233  }
234  }
235 
236  void JSONObject::get(const Json::Value& val, float& result) const
237  {
238  if (!val.isNumeric())
239  {
240  throw JSONInvalidDataTypeException();
241  }
242  else
243  {
244  result = val.asFloat();
245  }
246  }
247 
248  void JSONObject::get(const Json::Value& val, double& result) const
249  {
250  if (!val.isNumeric())
251  {
252  throw JSONInvalidDataTypeException();
253  }
254  else
255  {
256  result = val.asDouble();
257  }
258  }
259 
260  void JSONObject::get(const Json::Value& val, std::string& result) const
261  {
262  if (!val.isString())
263  {
264  throw JSONInvalidDataTypeException();
265  }
266  else
267  {
268  result = val.asString();
269  }
270  }
271 
272  const Json::Value& JSONObject::getValue(const std::string& key) const
273  {
274  if (!jsonValue.isObject())
275  {
276  throw JSONInvalidDataTypeException("Attemping to get a key from a non object. key: " + key);
277  }
278  if (key.find_first_of('.') > 0)
279  {
280  // the following code allows to get child fields using dot notation,
281  // e.g "position.mean.x"
282  std::vector<std::string> keys = simox::alg::split(key, ".");
283  Json::Value const* result = &jsonValue[keys[0]];
284 
285  for (size_t i = 1; i < keys.size(); ++i)
286  if (result->isObject())
287  {
288  result = &((*result)[keys[i]]);
289  }
290  else
291  {
292  throw JSONInvalidFieldException(key);
293  }
294 
295  return *result;
296  }
297  else
298  {
299  return jsonValue[key];
300  }
301  }
302 
303  float JSONObject::getFloat(const ::std::string& key) const
304  {
305  const Json::Value& val = getValue(key);
306 
307  if (!val)
308  {
309  throw JSONInvalidFieldException(key);
310  }
311  else if (!val.isNumeric())
312  {
313  throw JSONInvalidDataTypeException();
314  }
315  else
316  {
317  return val.asFloat();
318  }
319  }
320 
321  double JSONObject::getDouble(const ::std::string& key) const
322  {
323  const Json::Value& val = getValue(key);
324 
325  if (!val)
326  {
327  throw JSONInvalidFieldException(key);
328  }
329  else if (!val.isNumeric())
330  {
331  throw JSONInvalidDataTypeException();
332  }
333  else
334  {
335  return val.asDouble();
336  }
337  }
338 
339  int JSONObject::getInt(const ::std::string& key) const
340  {
341  const Json::Value& val = getValue(key);
342 
343  if (!val)
344  {
345  throw JSONInvalidFieldException(key);
346  }
347  else if (!val.isInt())
348  {
349  throw JSONInvalidDataTypeException();
350  }
351  else
352  {
353  return val.asInt();
354  }
355  }
356 
357  bool JSONObject::getBool(const ::std::string& key) const
358  {
359  const Json::Value& val = getValue(key);
360 
361  if (!val)
362  {
363  throw JSONInvalidFieldException(key);
364  }
365  else if (!val.isBool())
366  {
367  throw JSONInvalidDataTypeException();
368  }
369  else
370  {
371  return val.asBool();
372  }
373  }
374 
375  std::string JSONObject::getString(const ::std::string& key) const
376  {
377  const Json::Value& val = getValue(key);
378 
379  if (!val)
380  {
381  ARMARX_IMPORTANT_S << "Invalid Field Exception for: " << key << " of object: \n" << this->asString(true);
382  throw JSONInvalidFieldException(key);
383  }
384  else if (!val.isString())
385  {
386  throw JSONInvalidDataTypeException();
387  }
388  else
389  {
390  return val.asString();
391  }
392  }
393 
395  {
396  if (!jsonValue.isArray())
397  {
398  throw JSONInvalidDataTypeException();
399  }
400  else if (index >= jsonValue.size())
401  {
402  throw JSONInvalidArrayIndexException();
403  }
404  else
405  {
407  elem->jsonValue = jsonValue[index];
408  return elem;
409  }
410  }
411 
412  armarx::AbstractObjectSerializerPtr JSONObject::getElement(const std::string& key) const
413  {
414  if (!jsonValue.isObject())
415  {
416  throw JSONInvalidDataTypeException();
417  }
418  else if (!jsonValue.isMember(key))
419  {
420  throw JSONInvalidFieldException(key);
421  }
422  else
423  {
425  elem->jsonValue = jsonValue[key];
426  return elem;
427  }
428  }
429 
430  std::vector<std::string> JSONObject::getElementNames() const
431  {
432  if (!jsonValue.isObject())
433  {
434  throw JSONInvalidDataTypeException();
435  }
436  else
437  {
438  return jsonValue.getMemberNames();
439  }
440  }
441 
442  void JSONObject::getVariantArray(const std::string& key, std::vector<VariantPtr>& result)
443  {
444  const Json::Value& arrValue = getValue(key);
445 
446  if (!arrValue.isArray())
447  {
448  throw JSONInvalidDataTypeException();
449  }
450 
451  result.clear();
452  result.resize(arrValue.size());
453 
454  for (size_t i = 0; i < arrValue.size(); ++i)
455  {
456  JSONObjectPtr json = JSONObjectPtr::dynamicCast(createElement());
457  json->jsonValue = arrValue[int(i)];
458  VariantPtr var = json->deserializeVariant();
459  result.at(i) = var;
460  }
461  }
462 
463  void JSONObject::getVariantMap(const std::string& key, StringVariantBaseMap& result)
464  {
465  const Json::Value& arrValue = getValue(key);
466 
467  if (!arrValue.isArray())
468  {
469  throw JSONInvalidDataTypeException();
470  }
471 
472  result.clear();
473 
474  for (size_t i = 0; i < arrValue.size(); ++i)
475  {
476  JSONObjectPtr json = JSONObjectPtr::dynamicCast(createElement());
477  json->jsonValue = arrValue[int(i)];
478  VariantPtr var = json->getVariant("variant");
479  result[json->getString("key")] = var;
480  }
481  }
482 
483  armarx::ElementType JSONObject::getElementType(const ::Ice::Current&) const
484  {
485  if (jsonValue.isArray())
486  {
488  }
489  else if (jsonValue.isObject())
490  {
492  }
493  else
494  {
496  }
497  }
498 
499  void JSONObject::setElementType(armarx::ElementType elementType, const ::Ice::Current&)
500  {
501  switch (elementType)
502  {
504  jsonValue = Json::Value();
505  break;
506 
508  jsonValue = Json::Value(Json::arrayValue);
509  break;
510 
512  default:
513  jsonValue = Json::Value(Json::objectValue);
514  break;
515  }
516  }
517 
519  {
520  jsonValue.clear();
521  }
522 
524  {
525  JSONObjectPtr var ;
526 
527  if (variant)
528  {
529  var = JSONObjectPtr::dynamicCast(serializer->serializeVariant(VariantPtr::dynamicCast(variant)));
530  }
531  else
532  {
533  var = serializer;
534  }
535 
536  StringVariantBaseMap result;
537 
538  for (size_t i = 0; i < var->size(); i++)
539  {
540  // JSONObjectPtr elem = JSONObjectPtr::dynamicCast(var->getElement(i));
541  auto names = var->getElementNames();
542 
543  for (auto name : names)
544  {
545  JSONObjectPtr elem = JSONObjectPtr::dynamicCast(var->getElement(name));
546 
547  if (elem->getElementType() == armarx::ElementTypes::eScalar)
548  {
549  if (elem->jsonValue.isBool())
550  {
551  result[name] = new Variant(var->getBool(name));
552  }
553  else if (elem->jsonValue.isString())
554  {
555  result[name] = new Variant(var->getString(name));
556  }
557  else if (elem->jsonValue.isDouble())
558  {
559  result[name] = new Variant(var->getDouble(name));
560  }
561  else if (elem->jsonValue.isInt())
562  {
563  result[name] = new Variant(var->getInt(name));
564  }
565  else
566  {
567  throw LocalException() << "Unhandled type in variant to Dict conversion: " << elem->jsonValue.type();
568  }
569  }
570  else
571  {
572  auto subResult = ConvertToBasicVariantMap(elem, nullptr);
573 
574  for (auto& entry : subResult)
575  {
576  result[name + "." + entry.first] = entry.second;
577  }
578  }
579  }
580  }
581 
582  return result;
583  }
584 }
armarx::Variant
The Variant class is described here: Variants.
Definition: Variant.h:224
armarx::JSONObject::getElement
armarx::AbstractObjectSerializerPtr getElement(unsigned int index) const override
Definition: JSONObject.cpp:394
armarx::JSONObject::hasElement
bool hasElement(const ::std::string &key) const override
Definition: JSONObject.cpp:207
ARMARX_IMPORTANT_S
#define ARMARX_IMPORTANT_S
Definition: Logging.h:203
ColorMap::Value
Value
Color maps that associate a color to every float from [0..1].
Definition: color.h:16
cyberglove_with_calib_22dof.ic
ic
Definition: cyberglove_with_calib_22dof.py:22
armarx::JSONObject::append
void append(const armarx::AbstractObjectSerializerPtr &val) override
Definition: JSONObject.cpp:171
armarx::StringVariantBaseMap
std::map< std::string, VariantBasePtr > StringVariantBaseMap
Definition: ManagedIceObject.h:111
LocalException.h
JSONObject.h
armarx::JSONObject::setVariantMap
void setVariantMap(const ::std::string &key, const armarx::StringVariantBaseMap &val) override
Definition: JSONObject.cpp:143
index
uint8_t index
Definition: EtherCATFrame.h:59
armarx::JSONObject::ConvertToBasicVariantMap
static StringVariantBaseMap ConvertToBasicVariantMap(const JSONObjectPtr &serializer, const VariantBasePtr &variant)
Definition: JSONObject.cpp:523
armarx::JSONObject::reset
void reset() override
Definition: JSONObject.cpp:518
armarx::ElementTypes::eArray
@ eArray
Definition: AbstractObjectSerializer.h:36
armarx::JSONObject::setString
void setString(const ::std::string &key, const std::string &val) override
Definition: JSONObject.h:156
armarx::JSONObject
The JSONObject class is used to represent and (de)serialize JSON objects.
Definition: JSONObject.h:43
armarx::AbstractObjectSerializer::setVariant
virtual void setVariant(const ::std::string &key, const VariantPtr &val)
Definition: AbstractObjectSerializer.cpp:230
armarx::JSONObject::getDouble
double getDouble(const ::std::string &key) const override
Definition: JSONObject.cpp:321
armarx::AbstractObjectSerializer::getIdField
std::string getIdField() const
Definition: AbstractObjectSerializer.h:126
armarx::ElementTypes::eObject
@ eObject
Definition: AbstractObjectSerializer.h:35
IceUtil
Definition: Instance.h:21
armarx::JSONObject::set
void set(const ::std::string &key, T val)
Definition: JSONObject.h:111
armarx::JSONObject::toString
std::string toString(const ::Ice::Current &=Ice::emptyCurrent) const override
Definition: JSONObject.cpp:58
armarx::AbstractObjectSerializer::serializeVariant
AbstractObjectSerializerPtr serializeVariant(const VariantPtr &val) const
Definition: AbstractObjectSerializer.cpp:59
armarx::JSONObject::getString
std::string getString(const ::std::string &key) const override
Definition: JSONObject.cpp:375
armarx::JSONObject::getVariantMap
void getVariantMap(const ::std::string &key, armarx::StringVariantBaseMap &result) override
Definition: JSONObject.cpp:463
IceInternal::Handle< ::Ice::Communicator >
armarx::JSONObject::getJsonValue
const Json::Value & getJsonValue() const
Definition: JSONObject.cpp:93
armarx::JSONObject::~JSONObject
~JSONObject() override
Definition: JSONObject.cpp:54
armarx::JSONObject::setElement
void setElement(const ::std::string &key, const armarx::AbstractObjectSerializerPtr &obj) override
Definition: JSONObject.cpp:104
armarx::JSONObject::createElement
armarx::AbstractObjectSerializerPtr createElement() const override
Definition: JSONObject.cpp:98
armarx::JSONObject::fromString
void fromString(const ::std::string &jsonString, const ::Ice::Current &=Ice::emptyCurrent) override
Definition: JSONObject.cpp:86
armarx::JSONObject::getElementNames
std::vector< std::string > getElementNames() const override
Definition: JSONObject.cpp:430
armarx::JSONObjectPtr
IceInternal::Handle< JSONObject > JSONObjectPtr
Definition: JSONObject.h:34
armarx::ElementTypes::eScalar
@ eScalar
Definition: AbstractObjectSerializer.h:34
armarx::JSONObject::merge
void merge(const armarx::AbstractObjectSerializerPtr &val) override
Definition: JSONObject.cpp:185
armarx::ElementTypes::ElementType
ElementType
Definition: AbstractObjectSerializer.h:32
armarx::JSONObject::getVariantArray
void getVariantArray(const ::std::string &key, std::vector< armarx::VariantPtr > &result) override
Definition: JSONObject.cpp:442
armarx::AbstractObjectSerializer::ic
Ice::CommunicatorPtr ic
Definition: AbstractObjectSerializer.h:166
armarx::AbstractObjectSerializer::setIdField
void setIdField(const std::string &fieldName)
Definition: AbstractObjectSerializer.h:130
armarx::JSONObject::setVariantArray
void setVariantArray(const ::std::string &key, const std::vector< armarx::VariantBasePtr > &val) override
armarx::viz::data::ElementFlags::names
const simox::meta::IntEnumNames names
Definition: json_elements.cpp:14
armarx::JSONObject::JSONObject
JSONObject(armarx::ElementType nodeType=armarx::ElementTypes::eObject, const Ice::CommunicatorPtr ic=Ice::CommunicatorPtr())
Definition: JSONObject.cpp:34
armarx::JSONObject::getInt
int getInt(const ::std::string &key) const override
Definition: JSONObject.cpp:339
armarx::AbstractObjectSerializerPtr
IceInternal::Handle< AbstractObjectSerializer > AbstractObjectSerializerPtr
Definition: AbstractObjectSerializer.h:45
armarx::JSONObject::size
unsigned int size() const override
Definition: JSONObject.cpp:202
armarx::JSONObject::getFloat
float getFloat(const ::std::string &key) const override
Definition: JSONObject.cpp:303
Logging.h
armarx::JSONObject::asString
std::string asString(bool pretty=false) const
Definition: JSONObject.cpp:63
armarx::JSONObject::setElementType
void setElementType(armarx::ElementType nodeType, const ::Ice::Current &=Ice::emptyCurrent) override
Definition: JSONObject.cpp:499
armarx::JSONObject::getElementType
armarx::ElementType getElementType(const ::Ice::Current &=Ice::emptyCurrent) const override
Definition: JSONObject.cpp:483
armarx::JSONObject::getBool
bool getBool(const ::std::string &key) const override
Definition: JSONObject.cpp:357
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::split
std::vector< std::string > split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
Definition: StringHelpers.cpp:36
armarx::AbstractObjectSerializer
Definition: AbstractObjectSerializer.h:52