Ref T264, improved detection of multiple container formats

This commit is contained in:
Klaus Basan
2018-05-22 11:20:24 +02:00
parent ef3f312bc5
commit 1d8bbaf3be
4 changed files with 82 additions and 26 deletions

View File

@@ -7,19 +7,21 @@
* contained in the LICENSE file.
*/
#include "blackmisc/db/datastoreobjectlist.h"
#include "blackmisc/predicates.h"
#include "blackmisc/countrylist.h"
#include "blackmisc/simulation/aircraftmodellist.h"
#include "blackmisc/simulation/distributorlist.h"
#include "blackmisc/aviation/airport.h"
#include "blackmisc/aviation/airportlist.h"
#include "blackmisc/aviation/liverylist.h"
#include "blackmisc/aviation/aircrafticaocodelist.h"
#include "blackmisc/aviation/airlineicaocodelist.h"
#include "blackmisc/db/datastoreobjectlist.h"
#include "blackmisc/db/dbinfolist.h"
#include "blackmisc/db/artifactlist.h"
#include "blackmisc/db/distributionlist.h"
#include "blackmisc/simulation/aircraftmodellist.h"
#include "blackmisc/simulation/distributorlist.h"
#include "blackmisc/predicates.h"
#include "blackmisc/countrylist.h"
#include "blackmisc/json.h"
#include "blackmisc/variantprivate.h"
#include <QJsonObject>
#include <QJsonValue>
@@ -205,15 +207,16 @@ namespace BlackMisc
return c;
}
if (Json::looksLikeSwiftDataObject(jsonObject))
// cache or settings format?
if (Json::looksLikeSwiftDataObjectJson(jsonObject))
{
const QJsonObject cacheObj = Json::swiftDataObjectValue(jsonObject);
// swift own format
CONTAINER container;
container.convertFromJson(cacheObj);
Private::CValueObjectMetaInfoHelper::convertFromMemoizedJson(cacheObj, container, true, 0); // handles both, memoized or "normal" convertFromJson
return container;
}
// plain vanilla container, does not match memoized objects
if (Json::looksLikeSwiftContainerJson(jsonObject))
{
CONTAINER container;
@@ -221,9 +224,18 @@ namespace BlackMisc
return container;
}
// still as type/value pair
if (Json::looksLikeSwiftTypeValuePairJson(jsonObject))
{
const QJsonObject valueObject = jsonObject.value("value").toObject();
CONTAINER container;
Private::CValueObjectMetaInfoHelper::convertFromMemoizedJson(valueObject, container, true, 0); // handles both, memoized or "normal" convertFromJson
return container;
}
// DB format, as array
if (jsonObject.contains("data"))
{
// DB format
return IDatastoreObjectList::fromDatabaseJson(jsonObject.value("data").toArray());
}
@@ -231,6 +243,20 @@ namespace BlackMisc
throw CJsonException("Unsupported JSON format");
}
template<class OBJ, class CONTAINER, typename KEYTYPE>
CONTAINER IDatastoreObjectList<OBJ, CONTAINER, KEYTYPE>::fromMultipleJsonFormats(const QString &jsonString)
{
// also accept cache format
if (jsonString.isEmpty())
{
const CONTAINER c;
return c;
}
const QJsonObject jo = Json::jsonObjectFromString(jsonString, false);
return IDatastoreObjectList<OBJ, CONTAINER, KEYTYPE>::fromMultipleJsonFormats(jo);
}
template<class OBJ, class CONTAINER, typename KEYTYPE>
QDateTime IDatastoreObjectList<OBJ, CONTAINER, KEYTYPE>::latestDbTimestamp() const
{

View File

@@ -70,6 +70,10 @@ namespace BlackMisc
//! \remark supports native swift C++ format, DB format, and cache format
static CONTAINER fromMultipleJsonFormats(const QJsonObject &jsonObject);
//! From multiple JSON formats
//! \remark supports native swift C++ format, DB format, and cache format
static CONTAINER fromMultipleJsonFormats(const QString &jsonString);
//! From DB JSON with default prefixes
//! \remark Specialized classes might have their own fromDatabaseJson implementation
static CONTAINER fromDatabaseJson(const QJsonArray &array);

View File

@@ -58,7 +58,7 @@ const QJsonValue &operator >>(const QJsonValue &json, QString &value)
const QJsonValue &operator >>(const QJsonValue &json, QStringList &value)
{
for (auto && element : json.toArray()) { value << element.toString(); }
for (auto &&element : json.toArray()) { value << element.toString(); }
return json;
}
@@ -132,7 +132,7 @@ QJsonValueRef operator >>(QJsonValueRef json, QString &value)
QJsonValueRef operator >>(QJsonValueRef json, QStringList &value)
{
for (auto && element : json.toArray()) { value << element.toString(); }
for (auto &&element : json.toArray()) { value << element.toString(); }
return json;
}
@@ -473,16 +473,31 @@ namespace BlackMisc
return looksLikeJson(json);
}
bool looksLikeSwiftDataObject(const QJsonObject &object)
bool looksLikeSwiftDataObjectJson(const QJsonObject &object)
{
// key
// - type
// - value
if (object.size() != 1) { return false; }
const QString key = object.keys().front();
const QStringList keys = object.keys();
if (keys.size() != 1) { return false; }
const QString key = keys.front();
const QJsonObject cacheObject = object.value(key).toObject();
return (cacheObject.contains("type") && cacheObject.contains("value"));
}
QJsonObject swiftDataObjectValue(const QString &jsonString)
{
const QJsonObject obj = jsonObjectFromString(jsonString);
if (obj.isEmpty()) { return obj; }
return swiftDataObjectValue(obj);
}
QJsonObject swiftDataObjectValue(const QJsonObject &object)
{
// key
// - type
// - value
if (object.size() != 1) { return object; } // no cache format
const QString key = object.keys().front();
const QJsonObject cacheObject = object.value(key).toObject();
@@ -510,13 +525,6 @@ namespace BlackMisc
return object;
}
QJsonObject swiftDataObjectValue(const QString &jsonString)
{
const QJsonObject obj = jsonObjectFromString(jsonString);
if (obj.isEmpty()) { return obj; }
return swiftDataObjectValue(obj);
}
QJsonObject unwrapCache(const QString &jsonString)
{
@@ -530,5 +538,15 @@ namespace BlackMisc
// CContainerbase::convertFromJson
return object.contains("containerbase");
}
bool looksLikeSwiftTypeValuePairJson(const QJsonObject &object)
{
return (object.contains("type") && object.contains("value"));
}
bool looksLikeSwiftDbJson(const QJsonObject &object)
{
return (object.contains("data"));
}
} // ns
} // ns

View File

@@ -261,26 +261,34 @@ namespace BlackMisc
//! \remark Quick check if the string could be a valid swift JSON string
BLACKMISC_EXPORT bool looksLikeSwiftJson(const QString &json);
//! Looks like a valid swift container JSON object
//! Looks like a valid swift container JSON object?
BLACKMISC_EXPORT bool looksLikeSwiftContainerJson(const QJsonObject &object);
//! Looks like a cache/setting object
BLACKMISC_EXPORT bool looksLikeSwiftDataObject(const QJsonObject &object);
//! Looks like a cache/setting object?
BLACKMISC_EXPORT bool looksLikeSwiftDataObjectJson(const QJsonObject &object);
//! The value of a cache/setting object
//! Looks like a swift type/value pair?
BLACKMISC_EXPORT bool looksLikeSwiftTypeValuePairJson(const QJsonObject &object);
//! Looks like a swift DB format?
BLACKMISC_EXPORT bool looksLikeSwiftDbJson(const QJsonObject &object);
//! The value part of a cache/setting object
//! \remark if data object unstrip from that, otherwise leave unchanged
//! \remark this is the value ONLY!
BLACKMISC_EXPORT QJsonObject swiftDataObjectValue(const QJsonObject &object);
//! The value of a cache/setting object
//! \remark if data object unstrip from that, otherwise leave unchanged
//! \remark this is the value ONLY!
BLACKMISC_EXPORT QJsonObject swiftDataObjectValue(const QString &jsonString);
//! The value of a cache/setting object
//! The type/value of a cache/setting object
//! \remark if cache object unstrip from that, otherwise leave unchanged
//! \remark format is type/value
BLACKMISC_EXPORT QJsonObject unwrapCache(const QJsonObject &object);
//! The value of a cache/setting object
//! The type/value object of a cache/setting object
//! \remark if cache object unstrip from that, otherwise leave unchanged
//! \remark format is type/value
BLACKMISC_EXPORT QJsonObject unwrapCache(const QString &jsonString);