Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
PIM
KItinerary
Commits
2fab2b3e
Commit
2fab2b3e
authored
Jul 25, 2021
by
Volker Krause
Browse files
Allow to register custom types for JSON-LD deserialization
parent
3cc7e1f9
Pipeline
#71829
passed with stage
in 13 minutes and 2 seconds
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
src/lib/datatypes/datatypes.h
View file @
2fab2b3e
...
...
@@ -72,6 +72,7 @@ public: \
bool operator==(const Class &other) const; \
inline bool operator!=(const Class &other) const { return !(*this == other); } \
operator QVariant () const; \
static const char* typeName(); \
private:
#define KITINERARY_BASE_GADGET(Class) \
...
...
src/lib/datatypes/datatypes_p.h
View file @
2fab2b3e
...
...
@@ -85,6 +85,7 @@ Class::~Class() = default; \
Class& Class::operator=(const Class &other) { d = other.d; return *this; } \
QString Class::className() const { return QStringLiteral(#Class); } \
Class::operator QVariant() const { return QVariant::fromValue(*this); } \
const char* Class::typeName() { return #Class; } \
static_assert(sizeof(Class) == sizeof(void*), "dptr must be the only member!"); \
namespace detail { \
static constexpr int property_counter(num<0>, tag<Class>) { return 1; } \
...
...
src/lib/jsonlddocument.cpp
View file @
2fab2b3e
...
...
@@ -31,10 +31,83 @@
#include
<QUrl>
#include
<QTimeZone>
#include
<cassert>
#include
<cmath>
#include
<cstring>
using
namespace
KItinerary
;
struct
TypeInfo
{
const
char
*
name
;
const
QMetaObject
*
mo
;
int
metaTypeId
;
};
static
void
registerBuiltInTypes
(
std
::
vector
<
TypeInfo
>
&
r
);
static
std
::
vector
<
TypeInfo
>&
typeResgistry
()
{
static
std
::
vector
<
TypeInfo
>
s_typeResgistry
;
if
(
s_typeResgistry
.
empty
())
{
registerBuiltInTypes
(
s_typeResgistry
);
}
return
s_typeResgistry
;
}
template
<
typename
T
>
static
void
add
(
std
::
vector
<
TypeInfo
>
&
registry
)
{
registry
.
push_back
({
T
::
typeName
(),
&
T
::
staticMetaObject
,
qMetaTypeId
<
T
>
()
});
}
static
void
registerBuiltInTypes
(
std
::
vector
<
TypeInfo
>
&
r
)
{
add
<
Action
>
(
r
);
add
<
Airline
>
(
r
);
add
<
Airport
>
(
r
);
add
<
Brand
>
(
r
);
add
<
BusReservation
>
(
r
);
add
<
BusStation
>
(
r
);
add
<
BusTrip
>
(
r
);
add
<
CancelAction
>
(
r
);
add
<
CheckInAction
>
(
r
);
add
<
CreativeWork
>
(
r
);
add
<
DigitalDocument
>
(
r
);
add
<
DownloadAction
>
(
r
);
add
<
EmailMessage
>
(
r
);
add
<
Event
>
(
r
);
add
<
EventReservation
>
(
r
);
add
<
Flight
>
(
r
);
add
<
FlightReservation
>
(
r
);
add
<
FoodEstablishment
>
(
r
);
add
<
FoodEstablishmentReservation
>
(
r
);
add
<
GeoCoordinates
>
(
r
);
add
<
LocalBusiness
>
(
r
);
add
<
LodgingBusiness
>
(
r
);
add
<
LodgingReservation
>
(
r
);
add
<
Organization
>
(
r
);
add
<
Person
>
(
r
);
add
<
Place
>
(
r
);
add
<
PostalAddress
>
(
r
);
add
<
RentalCar
>
(
r
);
add
<
RentalCarReservation
>
(
r
);
add
<
ReserveAction
>
(
r
);
add
<
Seat
>
(
r
);
add
<
Taxi
>
(
r
);
add
<
TaxiReservation
>
(
r
);
add
<
Ticket
>
(
r
);
add
<
TouristAttraction
>
(
r
);
add
<
TouristAttractionVisit
>
(
r
);
add
<
TrainReservation
>
(
r
);
add
<
TrainStation
>
(
r
);
add
<
TrainTrip
>
(
r
);
add
<
UpdateAction
>
(
r
);
add
<
ViewAction
>
(
r
);
assert
(
std
::
is_sorted
(
r
.
begin
(),
r
.
end
(),
[](
const
auto
&
lhs
,
const
auto
&
rhs
)
{
return
std
::
strcmp
(
lhs
.
name
,
rhs
.
name
)
<
0
;
}));
}
static
QVariant
createInstance
(
const
QJsonObject
&
obj
);
// Eurowings workarounds...
...
...
@@ -177,62 +250,19 @@ static void createInstance(const QMetaObject *mo, void *v, const QJsonObject &ob
}
}
template
<
typename
T
>
static
QVariant
createInstance
(
const
QJsonObject
&
obj
)
{
T
t
;
createInstance
(
&
T
::
staticMetaObject
,
&
t
,
obj
);
return
QVariant
::
fromValue
(
t
);
}
#define MAKE_FACTORY(Class) \
if (type == QLatin1String(#Class)) \
return createInstance<Class>(obj)
static
QVariant
createInstance
(
const
QJsonObject
&
obj
)
{
const
auto
type
=
obj
.
value
(
QLatin1String
(
"@type"
)).
toString
();
MAKE_FACTORY
(
Action
);
MAKE_FACTORY
(
Airline
);
MAKE_FACTORY
(
Airport
);
MAKE_FACTORY
(
Brand
);
MAKE_FACTORY
(
BusReservation
);
MAKE_FACTORY
(
BusStation
);
MAKE_FACTORY
(
BusTrip
);
MAKE_FACTORY
(
CancelAction
);
MAKE_FACTORY
(
CheckInAction
);
MAKE_FACTORY
(
CreativeWork
);
MAKE_FACTORY
(
DigitalDocument
);
MAKE_FACTORY
(
DownloadAction
);
MAKE_FACTORY
(
EmailMessage
);
MAKE_FACTORY
(
Event
);
MAKE_FACTORY
(
EventReservation
);
MAKE_FACTORY
(
Flight
);
MAKE_FACTORY
(
FlightReservation
);
MAKE_FACTORY
(
FoodEstablishment
);
MAKE_FACTORY
(
FoodEstablishmentReservation
);
MAKE_FACTORY
(
LocalBusiness
);
MAKE_FACTORY
(
RentalCarReservation
);
MAKE_FACTORY
(
RentalCar
);
MAKE_FACTORY
(
ReserveAction
);
MAKE_FACTORY
(
GeoCoordinates
);
MAKE_FACTORY
(
LodgingBusiness
);
MAKE_FACTORY
(
LodgingReservation
);
MAKE_FACTORY
(
Organization
);
MAKE_FACTORY
(
Person
);
MAKE_FACTORY
(
Place
);
MAKE_FACTORY
(
PostalAddress
);
MAKE_FACTORY
(
Seat
);
MAKE_FACTORY
(
TaxiReservation
);
MAKE_FACTORY
(
Taxi
);
MAKE_FACTORY
(
Ticket
);
MAKE_FACTORY
(
TouristAttraction
);
MAKE_FACTORY
(
TouristAttractionVisit
);
MAKE_FACTORY
(
TrainReservation
);
MAKE_FACTORY
(
TrainStation
);
MAKE_FACTORY
(
TrainTrip
);
MAKE_FACTORY
(
UpdateAction
);
MAKE_FACTORY
(
ViewAction
);
const
auto
&
registry
=
typeResgistry
();
const
auto
it
=
std
::
lower_bound
(
registry
.
begin
(),
registry
.
end
(),
type
,
[](
const
auto
&
lhs
,
const
auto
&
rhs
)
{
return
QLatin1String
(
lhs
.
name
)
<
rhs
;
});
if
(
it
!=
registry
.
end
()
&&
QLatin1String
((
*
it
).
name
)
==
type
)
{
QVariant
value
((
*
it
).
metaTypeId
,
nullptr
);
createInstance
((
*
it
).
mo
,
value
.
data
(),
obj
);
return
value
;
}
if
(
type
==
QLatin1String
(
"QDateTime"
))
{
auto
dt
=
QDateTime
::
fromString
(
obj
.
value
(
QLatin1String
(
"@value"
)).
toString
(),
Qt
::
ISODate
);
...
...
@@ -242,7 +272,6 @@ static QVariant createInstance(const QJsonObject &obj)
return
{};
}
#undef MAKE_FACTORY
QVector
<
QVariant
>
JsonLdDocument
::
fromJson
(
const
QJsonArray
&
array
)
{
...
...
@@ -525,3 +554,16 @@ QVariant JsonLdDocument::apply(const QVariant& lhs, const QVariant& rhs)
return
res
;
}
void
JsonLdDocument
::
registerType
(
const
char
*
typeName
,
const
QMetaObject
*
mo
,
int
metaTypeId
)
{
auto
&
registry
=
typeResgistry
();
const
auto
it
=
std
::
lower_bound
(
registry
.
begin
(),
registry
.
end
(),
typeName
,
[](
const
auto
&
lhs
,
const
auto
*
rhs
)
{
return
std
::
strcmp
(
lhs
.
name
,
rhs
)
<
0
;
});
if
(
it
!=
registry
.
end
()
&&
std
::
strcmp
((
*
it
).
name
,
typeName
)
==
0
)
{
qCWarning
(
Log
)
<<
"Type already registered:"
<<
typeName
;
}
else
{
registry
.
insert
(
it
,
{
typeName
,
mo
,
metaTypeId
});
}
}
src/lib/jsonlddocument.h
View file @
2fab2b3e
...
...
@@ -59,8 +59,16 @@ public:
*/
KITINERARY_EXPORT
static
QVariant
apply
(
const
QVariant
&
lhs
,
const
QVariant
&
rhs
);
/** Register a custom type for deserialization. */
template
<
typename
T
>
inline
void
registerType
()
{
registerType
(
T
::
typeName
(),
&
T
::
staticMetaObject
,
qMetaTypeId
<
T
>
());
}
private:
KITINERARY_EXPORT
static
void
writePropertyImpl
(
const
QMetaObject
*
mo
,
void
*
obj
,
const
char
*
name
,
const
QVariant
&
value
);
KITINERARY_EXPORT
static
void
registerType
(
const
char
*
typeName
,
const
QMetaObject
*
mo
,
int
metaTypeId
);
};
template
<
typename
T
>
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment