#pragma once // QT include #include #include #include #include #include class QJsonUtils { public: static void modify(QJsonObject& value, QStringList path, const QJsonValue& newValue = QJsonValue::Null, QString propertyName = "") { QJsonObject result; if (!path.isEmpty()) { if (path.first() == "[root]") path.removeFirst(); for (QStringList::iterator it = path.begin(); it != path.end(); ++it) { QString current = *it; if (current.left(1) == ".") *it = current.mid(1, current.size()-1); } if (!value.isEmpty()) modifyValue(value, result, path, newValue, propertyName); else if (newValue != QJsonValue::Null && !propertyName.isEmpty()) result[propertyName] = newValue; } value = result; } static QJsonValue create(QJsonValue schema, bool ignoreRequired = false) { return createValue(schema, ignoreRequired); } static QString getDefaultValue(const QJsonValue & value) { QString ret; switch (value.type()) { case QJsonValue::Array: { for (const QJsonValueRef v : value.toArray()) { ret = getDefaultValue(v); if (!ret.isEmpty()) break; } break; } case QJsonValue::Object: ret = getDefaultValue(value.toObject().find("default").value()); break; case QJsonValue::Bool: return value.toBool() ? "True" : "False"; case QJsonValue::Double: return QString::number(value.toDouble()); case QJsonValue::String: return value.toString(); case QJsonValue::Null: case QJsonValue::Undefined: break; } return ret; } private: static QJsonValue createValue(QJsonValue schema, bool ignoreRequired) { QJsonObject result; QJsonObject obj = schema.toObject(); if (obj.find("type") != obj.end() && obj.find("type").value().isString()) { QJsonValue ret = QJsonValue::Null; if (obj.find("type").value().toString() == "object" && ( obj.find("required").value().toBool() || ignoreRequired ) ) ret = createValue(obj["properties"], ignoreRequired); else if (obj.find("type").value().toString() == "array" && ( obj.find("required").value().toBool() || ignoreRequired ) ) { QJsonArray array; if (obj.find("default") != obj.end()) ret = obj.find("default").value(); else { ret = createValue(obj["items"], ignoreRequired); if (!ret.toObject().isEmpty()) array.append(ret); ret = array; } } else if ( obj.find("required").value().toBool() || ignoreRequired ) if (obj.find("default") != obj.end()) ret = obj.find("default").value(); return ret; } else { for (QJsonObject::const_iterator i = obj.begin(); i != obj.end(); ++i) { QString attribute = i.key(); const QJsonValue & attributeValue = *i; QJsonValue subValue = obj[attribute]; if (attributeValue.toObject().find("type") != attributeValue.toObject().end()) { if (attributeValue.toObject().find("type").value().toString() == "object" && ( attributeValue.toObject().find("required").value().toBool() || ignoreRequired ) ) { if (obj.contains("properties")) result[attribute] = createValue(obj["properties"], ignoreRequired); else result[attribute] = createValue(subValue, ignoreRequired); } else if (attributeValue.toObject().find("type").value().toString() == "array" && ( attributeValue.toObject().find("required").value().toBool() || ignoreRequired ) ) { QJsonArray array; if (attributeValue.toObject().find("default") != attributeValue.toObject().end()) result[attribute] = attributeValue.toObject().find("default").value(); else { QJsonValue retEmpty; retEmpty = createValue(attributeValue.toObject()["items"], ignoreRequired); if (!retEmpty.toObject().isEmpty()) array.append(retEmpty); result[attribute] = array; } } else if ( attributeValue.toObject().find("required").value().toBool() || ignoreRequired ) { if (attributeValue.toObject().find("default") != attributeValue.toObject().end()) result[attribute] = attributeValue.toObject().find("default").value(); else result[attribute] = QJsonValue::Null; } } } } return result; } static void modifyValue(QJsonValue source, QJsonObject& target, QStringList path, const QJsonValue& newValue, QString& property) { QJsonObject obj = source.toObject(); if (!obj.isEmpty()) { for (QJsonObject::iterator i = obj.begin(); i != obj.end(); ++i) { QString propertyName = i.key(); QJsonValue subValue = obj[propertyName]; if (subValue.isObject()) { if (!path.isEmpty()) { if (propertyName == path.first()) { path.removeFirst(); if (!path.isEmpty()) { QJsonObject obj; modifyValue(subValue, obj, path, newValue, property); subValue = obj; } else if (newValue != QJsonValue::Null) subValue = newValue; else continue; if (!subValue.toObject().isEmpty()) target[propertyName] = subValue; } else { if (path.first() == property && newValue != QJsonValue::Null) { target[property] = newValue; property = QString(); } target[propertyName] = subValue; } } else if (!subValue.toObject().isEmpty()) target[propertyName] = subValue; } else if (subValue.isArray()) { if (!path.isEmpty()) { if (propertyName == path.first()) { path.removeFirst(); int arrayLevel = -1; if (!path.isEmpty()) { if ((path.first().left(1) == "[") && (path.first().right(1) == "]")) { arrayLevel = path.first().mid(1, path.first().size()-2).toInt(); path.removeFirst(); } } QJsonArray array = subValue.toArray(); QJsonArray json_array; for (QJsonArray::iterator i = array.begin(); i != array.end(); ++i) { if (!path.isEmpty()) { QJsonObject arr; modifyValue(*i, arr, path, newValue, property); subValue = arr; } else if (newValue != QJsonValue::Null) subValue = newValue; else continue; if (!subValue.toObject().isEmpty()) json_array.append(subValue); else if (newValue != QJsonValue::Null && arrayLevel != -1) json_array.append( (i - array.begin() == arrayLevel) ? subValue : *i ); } if (!json_array.isEmpty()) target[propertyName] = json_array; else if (newValue != QJsonValue::Null && arrayLevel == -1) target[propertyName] = newValue; } else { if (path.first() == property && newValue != QJsonValue::Null) { target[property] = newValue; property = QString(); } target[propertyName] = subValue; } } else if (!subValue.toArray().isEmpty()) target[propertyName] = subValue; } else { if (!path.isEmpty()) { if (propertyName == path.first()) { path.removeFirst(); if (path.isEmpty()) { if (newValue != QJsonValue::Null && property.isEmpty()) subValue = newValue; else continue; } target[propertyName] = subValue; } else { if (path.first() == property && newValue != QJsonValue::Null) { target[property] = newValue; property = QString(); } target[propertyName] = subValue; } } else target[propertyName] = subValue; } } } else if (newValue != QJsonValue::Null && !property.isEmpty()) { target[property] = newValue; property = QString(); } } };