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