hyperion.ng
QJsonUtils.h
1 #pragma once
2 
3 // QT include
4 #include <QString>
5 #include <QStringList>
6 #include <QJsonObject>
7 #include <QJsonValue>
8 #include <QJsonArray>
9 
11 {
12 public:
13 
14  static void modify(QJsonObject& value, QStringList path, const QJsonValue& newValue = QJsonValue::Null, QString propertyName = "")
15  {
16  QJsonObject result;
17 
18  if (!path.isEmpty())
19  {
20  if (path.first() == "[root]")
21  path.removeFirst();
22 
23  for (QStringList::iterator it = path.begin(); it != path.end(); ++it)
24  {
25  QString current = *it;
26  if (current.left(1) == ".")
27  *it = current.mid(1, current.size()-1);
28  }
29 
30  if (!value.isEmpty())
31  modifyValue(value, result, path, newValue, propertyName);
32  else if (newValue != QJsonValue::Null && !propertyName.isEmpty())
33  result[propertyName] = newValue;
34  }
35 
36  value = result;
37  }
38 
39  static QJsonValue create(QJsonValue schema, bool ignoreRequired = false)
40  {
41  return createValue(schema, ignoreRequired);
42  }
43 
44 private:
45 
46  static QJsonValue createValue(QJsonValue schema, bool ignoreRequired)
47  {
48  QJsonObject result;
49  QJsonObject obj = schema.toObject();
50 
51  if (obj.find("type") != obj.end() && obj.find("type").value().isString())
52  {
53  QJsonValue ret = QJsonValue::Null;
54 
55  if (obj.find("type").value().toString() == "object" && ( obj.find("required").value().toBool() || ignoreRequired ) )
56  ret = createValue(obj["properties"], ignoreRequired);
57  else if (obj.find("type").value().toString() == "array" && ( obj.find("required").value().toBool() || ignoreRequired ) )
58  {
59  QJsonArray array;
60 
61  if (obj.find("default") != obj.end())
62  ret = obj.find("default").value();
63  else
64  {
65  ret = createValue(obj["items"], ignoreRequired);
66 
67  if (!ret.toObject().isEmpty())
68  array.append(ret);
69  ret = array;
70  }
71  }
72  else if ( obj.find("required").value().toBool() || ignoreRequired )
73  if (obj.find("default") != obj.end())
74  ret = obj.find("default").value();
75 
76  return ret;
77  }
78  else
79  {
80  for (QJsonObject::const_iterator i = obj.begin(); i != obj.end(); ++i)
81  {
82  QString attribute = i.key();
83  const QJsonValue & attributeValue = *i;
84  QJsonValue subValue = obj[attribute];
85 
86  if (attributeValue.toObject().find("type") != attributeValue.toObject().end())
87  {
88  if (attributeValue.toObject().find("type").value().toString() == "object" && ( attributeValue.toObject().find("required").value().toBool() || ignoreRequired ) )
89  {
90  if (obj.contains("properties"))
91  result[attribute] = createValue(obj["properties"], ignoreRequired);
92  else
93  result[attribute] = createValue(subValue, ignoreRequired);
94  }
95  else if (attributeValue.toObject().find("type").value().toString() == "array" && ( attributeValue.toObject().find("required").value().toBool() || ignoreRequired ) )
96  {
97  QJsonArray array;
98 
99  if (attributeValue.toObject().find("default") != attributeValue.toObject().end())
100  result[attribute] = attributeValue.toObject().find("default").value();
101  else
102  {
103  QJsonValue retEmpty;
104  retEmpty = createValue(attributeValue.toObject()["items"], ignoreRequired);
105 
106  if (!retEmpty.toObject().isEmpty())
107  array.append(retEmpty);
108  result[attribute] = array;
109  }
110  }
111  else if ( attributeValue.toObject().find("required").value().toBool() || ignoreRequired )
112  {
113  if (attributeValue.toObject().find("default") != attributeValue.toObject().end())
114  result[attribute] = attributeValue.toObject().find("default").value();
115  else
116  result[attribute] = QJsonValue::Null;
117  }
118  }
119  }
120  }
121 
122  return result;
123  }
124 
125  static void modifyValue(QJsonValue source, QJsonObject& target, QStringList path, const QJsonValue& newValue, QString& property)
126  {
127  QJsonObject obj = source.toObject();
128 
129  if (!obj.isEmpty())
130  {
131  for (QJsonObject::iterator i = obj.begin(); i != obj.end(); ++i)
132  {
133  QString propertyName = i.key();
134  QJsonValue subValue = obj[propertyName];
135 
136  if (subValue.isObject())
137  {
138  if (!path.isEmpty())
139  {
140  if (propertyName == path.first())
141  {
142  path.removeFirst();
143 
144  if (!path.isEmpty())
145  {
146  QJsonObject obj;
147  modifyValue(subValue, obj, path, newValue, property);
148  subValue = obj;
149  }
150  else if (newValue != QJsonValue::Null)
151  subValue = newValue;
152  else
153  continue;
154 
155  if (!subValue.toObject().isEmpty())
156  target[propertyName] = subValue;
157  }
158  else
159  {
160  if (path.first() == property && newValue != QJsonValue::Null)
161  {
162  target[property] = newValue;
163  property = QString();
164  }
165 
166  target[propertyName] = subValue;
167  }
168  }
169  else
170  if (!subValue.toObject().isEmpty())
171  target[propertyName] = subValue;
172  }
173  else if (subValue.isArray())
174  {
175  if (!path.isEmpty())
176  {
177  if (propertyName == path.first())
178  {
179  path.removeFirst();
180 
181  int arrayLevel = -1;
182  if (!path.isEmpty())
183  {
184  if ((path.first().left(1) == "[") && (path.first().right(1) == "]"))
185  {
186  arrayLevel = path.first().mid(1, path.first().size()-2).toInt();
187  path.removeFirst();
188  }
189  }
190 
191  QJsonArray array = subValue.toArray();
192  QJsonArray json_array;
193 
194  for (QJsonArray::iterator i = array.begin(); i != array.end(); ++i)
195  {
196  if (!path.isEmpty())
197  {
198  QJsonObject arr;
199  modifyValue(*i, arr, path, newValue, property);
200  subValue = arr;
201  }
202  else if (newValue != QJsonValue::Null)
203  subValue = newValue;
204  else
205  continue;
206 
207  if (!subValue.toObject().isEmpty())
208  json_array.append(subValue);
209  else if (newValue != QJsonValue::Null && arrayLevel != -1)
210  json_array.append( (i - array.begin() == arrayLevel) ? subValue : *i );
211  }
212 
213  if (!json_array.isEmpty())
214  target[propertyName] = json_array;
215  else if (newValue != QJsonValue::Null && arrayLevel == -1)
216  target[propertyName] = newValue;
217  }
218  else
219  {
220  if (path.first() == property && newValue != QJsonValue::Null)
221  {
222  target[property] = newValue;
223  property = QString();
224  }
225 
226  target[propertyName] = subValue;
227  }
228  }
229  else
230  if (!subValue.toArray().isEmpty())
231  target[propertyName] = subValue;
232  }
233  else
234  {
235  if (!path.isEmpty())
236  {
237  if (propertyName == path.first())
238  {
239  path.removeFirst();
240 
241  if (path.isEmpty())
242  {
243  if (newValue != QJsonValue::Null && property.isEmpty())
244  subValue = newValue;
245  else
246  continue;
247  }
248 
249  target[propertyName] = subValue;
250  }
251  else
252  {
253  if (path.first() == property && newValue != QJsonValue::Null)
254  {
255  target[property] = newValue;
256  property = QString();
257  }
258 
259  target[propertyName] = subValue;
260  }
261  }
262  else
263  target[propertyName] = subValue;
264  }
265  }
266  }
267  else if (newValue != QJsonValue::Null && !property.isEmpty())
268  {
269  target[property] = newValue;
270  property = QString();
271  }
272  }
273 };
Definition: QJsonUtils.h:10