Skip to content

Commit

Permalink
Qt5cpp Add support for nested containers (#7340)
Browse files Browse the repository at this point in the history
* Disable creation of empty json fields and fields for primitives which were not set, but using default values
modelnamePrefix will be the one passed from command line or SWG if none

* Updates after review
Also common http files are splitted
Update Petstore examples

* Small Fixes for cleaning up arrays of arrays/maps

* Changes
- Api Body pass by Reference, avoid seg fault due to deletion of auto constructed object passed as parameter.
- Support Maps and Arrays upto a depth of 2
- Refactor Helpers to handle Maps and simplify code

* Remove size check due to possible incorrect type

* Update PetStore Examples for Qt5 C++ and small fixes for QDate/QDateTime

* Updates after review. Fixes typo and remove usage of auto keyword.

* Restored usage of auto keyword.
  • Loading branch information
etherealjoy authored and wing328 committed Jan 14, 2018
1 parent 809e1f4 commit 0bf430a
Show file tree
Hide file tree
Showing 20 changed files with 701 additions and 262 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace {{this}} {
{{#operations}}
{{#operation}}
void
{{classname}}::{{nickname}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) {
{{classname}}::{{nickname}}({{#allParams}}{{{dataType}}}{{#isBodyParam}}&{{/isBodyParam}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) {
QString fullPath;
fullPath.append(this->host).append(this->basePath).append("{{{path}}}");
Expand Down Expand Up @@ -98,17 +98,17 @@ void

{{#bodyParams}}
{{#isContainer}}
QJsonArray* {{paramName}}Array = new QJsonArray();
toJsonArray((QList<void*>*){{paramName}}, {{paramName}}Array, QString("body"), QString("{{prefix}}User*"));
auto {{paramName}}_jobj = new QJsonObject();
toJsonArray((QList<void*>*){{paramName}}, {{paramName}}_jobj, QString("body"), QString("{{prefix}}User*"));

QJsonDocument doc(*{{paramName}}Array);
QJsonDocument doc(*{{paramName}}_jobj);
QByteArray bytes = doc.toJson();

input.request_body.append(bytes);
{{/isContainer}}
{{^isContainer}}{{#isString}}
QString output(*{{paramName}});{{/isString}}{{^isString}}
QString output = {{paramName}}.asJson();{{/isString}}
QString output(*{{paramName}});{{/isString}}{{#isByteArray}}QString output(*{{paramName}});{{/isByteArray}}{{^isString}}{{^isByteArray}}
QString output = {{paramName}}.asJson();{{/isByteArray}}{{/isString}}
input.request_body.append(output);
{{/isContainer}}{{/bodyParams}}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public:
QString basePath;
QMap<QString, QString> defaultHeaders;

{{#operations}}{{#operation}}void {{nickname}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{#operations}}{{#operation}}void {{nickname}}({{#allParams}}{{{dataType}}}{{#isBodyParam}}&{{/isBodyParam}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{/operation}}{{/operations}}
private:
{{#operations}}{{#operation}}void {{nickname}}Callback ({{prefix}}HttpRequestWorker * worker);
Expand Down
311 changes: 259 additions & 52 deletions modules/swagger-codegen/src/main/resources/qt5cpp/helpers-body.mustache

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ namespace {{this}} {
{{/cppNamespaceDeclarations}}

void setValue(void* value, QJsonValue obj, QString type, QString complexType);
void toJsonArray(QList<void*>* value, QJsonArray* output, QString innerName, QString innerType);
void toJsonArray(QList<void*>* value, QJsonObject* output, QString innerName, QString innerType);
void toJsonValue(QString name, void* value, QJsonObject* output, QString type);
void toJsonMap(QMap<QString, void*>* value, QJsonObject* output, QString innerName, QString innerType);
bool isCompatibleJsonValue(QString type);
QString stringValue(QString* value);
QString stringValue(qint32 value);
Expand Down
150 changes: 60 additions & 90 deletions modules/swagger-codegen/src/main/resources/qt5cpp/model-body.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,15 @@ void
{{classname}}::cleanup() {
{{#vars}}
{{#complexType}}
if({{name}} != nullptr) {
{{#isContainer}}{{#isListContainer}}QList<{{complexType}}*>* arr = {{name}};{{/isListContainer}}{{#isMapContainer}}QMap<QString, {{complexType}}*>* arr = {{name}};{{/isMapContainer}}
foreach({{complexType}}* o, *arr) {
if({{name}} != nullptr) { {{#isContainer}}
auto arr = {{name}};
for(auto o: *arr) { {{#items.isContainer}}
for(auto o1: *o) {
delete o1;
}{{/items.isContainer}}
delete o;
}
{{/isContainer}}delete {{name}};
}{{/isContainer}}
delete {{name}};
}{{/complexType}}
{{/vars}}
}
Expand All @@ -60,33 +63,30 @@ void
void
{{classname}}::fromJsonObject(QJsonObject &pJson) {
{{#vars}}
{{^isContainer}}
::{{cppNamespace}}::setValue(&{{name}}, pJson["{{baseName}}"], "{{baseType}}", "{{complexType}}");
{{/isContainer}}
{{#isListContainer}}
{{#complexType}}
::{{cppNamespace}}::setValue(&{{name}}, pJson["{{baseName}}"], "{{baseType}}", "{{complexType}}");
{{/complexType}}
{{^complexType}}
::{{cppNamespace}}::setValue(&{{name}}, pJson["{{baseName}}"], "{{baseType}}", "{{items.baseType}}");
{{/complexType}}
{{/isListContainer}}
{{#isMapContainer}}
if( pJson["{{baseName}}"].isObject()){
{{^isContainer}}::{{cppNamespace}}::setValue(&{{name}}, pJson["{{baseName}}"], "{{baseType}}", "{{complexType}}");{{/isContainer}}
{{#isContainer}}{{^items.isContainer}}::{{cppNamespace}}::setValue(&{{name}}, pJson["{{baseName}}"], "{{baseType}}", "{{items.baseType}}");{{/items.isContainer}}{{#items.isContainer}}{{#isListContainer}}
if(pJson["{{baseName}}"].isArray()){
auto arr = pJson["{{baseName}}"].toArray();
for (const QJsonValue & jval : arr) {
{{#items.isListContainer}}auto {{name}}_item = new QList<{{items.items.baseType}}{{^items.items.isLong}}{{^items.items.isInteger}}{{^items.items.isDouble}}{{^items.items.isFloat}}{{^items.items.isBoolean}}*{{/items.items.isBoolean}}{{/items.items.isFloat}}{{/items.items.isDouble}}{{/items.items.isInteger}}{{/items.items.isLong}}>();{{/items.isListContainer}}
{{#items.isMapContainer}}auto {{name}}_item = new QMap<QString, {{items.items.baseType}} {{^items.items.isLong}}{{^items.items.isInteger}}{{^items.items.isDouble}}{{^items.items.isFloat}}{{^items.items.isBoolean}}*{{/items.items.isBoolean}}{{/items.items.isFloat}}{{/items.items.isDouble}}{{/items.items.isInteger}}{{/items.items.isLong}}>();{{/items.isMapContainer}}
auto jsonval = jval.toObject();
::{{cppNamespace}}::setValue({{name}}_item, jsonval, "{{items.baseType}}", "{{items.items.baseType}}");
{{name}}->push_back({{name}}_item);
}
}{{/isListContainer}}{{#isMapContainer}}
if(pJson["{{baseName}}"].isObject()){
auto varmap = pJson["{{baseName}}"].toObject().toVariantMap();
if(varmap.count() > 0){
for(auto val : varmap.keys() ){
{
{{items.baseType}} *{{name}}_item = new {{items.baseType}}();
auto jsonval = QJsonValue::fromVariant(varmap[val]);
::{{cppNamespace}}::setValue(&{{name}}_item, jsonval, "{{items.baseType}}", "{{items.baseType}}");
{{name}}->insert({{name}}->end(), val, {{name}}_item);
}
for(auto val : varmap.keys()){
{{#items.isListContainer}}auto {{name}}_item = new QList<{{items.items.baseType}}{{^items.items.isLong}}{{^items.items.isInteger}}{{^items.items.isDouble}}{{^items.items.isFloat}}{{^items.items.isBoolean}}*{{/items.items.isBoolean}}{{/items.items.isFloat}}{{/items.items.isDouble}}{{/items.items.isInteger}}{{/items.items.isLong}}>();{{/items.isListContainer}}
{{#items.isMapContainer}}auto {{name}}_item = new QMap<QString, {{items.items.baseType}}{{^items.items.isLong}}{{^items.items.isInteger}}{{^items.items.isDouble}}{{^items.items.isFloat}}{{^items.items.isBoolean}}*{{/items.items.isBoolean}}{{/items.items.isFloat}}{{/items.items.isDouble}}{{/items.items.isInteger}}{{/items.items.isLong}}>();{{/items.isMapContainer}}
auto jsonval = QJsonValue::fromVariant(varmap.value(val));
::{{cppNamespace}}::setValue((QMap<QString, void *>*)&{{name}}_item, jsonval, "{{items.baseType}}", "{{items.items.baseType}}");
{{name}}->insert({{name}}->end(), val, {{name}}_item);
}
}
}

{{/isMapContainer}}
}{{/isMapContainer}}{{/items.isContainer}}{{/isContainer}}
{{/vars}}
}

Expand All @@ -104,77 +104,47 @@ QJsonObject*
{{classname}}::asJsonObject() {
QJsonObject* obj = new QJsonObject();
{{#vars}}
{{#complexType}}
{{^isContainer}}
{{#complexType}}
{{^isString}}
{{^isDateTime}}
{{^isContainer}}{{#complexType}}{{^isString}}{{^isDate}}{{^isDateTime}}{{^isByteArray}}
if({{name}}->isSet()){
toJsonValue(QString("{{baseName}}"), {{name}}, obj, QString("{{complexType}}"));
}
{{/isDateTime}}
{{/isString}}
{{#isString}}
}{{/isByteArray}}{{/isDateTime}}{{/isDate}}{{/isString}}{{#isString}}
if({{name}} != nullptr && *{{name}} != QString("")){
toJsonValue(QString("{{baseName}}"), {{name}}, obj, QString("{{complexType}}"));
}
{{/isString}}
{{/complexType}}
{{^complexType}}
if({{name}} != nullptr && *{{name}} != nullptr) {
obj->insert("{{name}}", QJsonValue(*{{name}}));
}
{{/complexType}}
{{/isContainer}}
{{#isListContainer}}
if({{name}}->size() > 0){
QJsonArray {{name}}JsonArray;
toJsonArray((QList<void*>*){{name}}, &{{name}}JsonArray, "{{name}}", "{{complexType}}");
obj->insert("{{baseName}}", {{name}}JsonArray);
}
{{/isListContainer}}
{{#isMapContainer}}
if({{name}}->size() > 0) {
QJsonObject {{name}}_jobj;
for(auto keyval : {{name}}->keys()){
toJsonValue(keyval, ((*{{name}})[keyval]), &{{name}}_jobj, "{{complexType}}");
}
obj->insert("{{baseName}}", {{name}}_jobj);
}
{{/isMapContainer}}
{{/complexType}}
{{^complexType}}
{{^isContainer}}
{{^isString}}
{{^isDateTime}}
}{{/isString}}{{/complexType}}{{#isPrimitiveType}}{{^isDateTime}}{{^isDate}}{{^isByteArray}}
if(m_{{name}}_isSet){
obj->insert("{{baseName}}", QJsonValue({{name}}));
}
{{/isDateTime}}
{{/isString}}
{{#isString}}
if({{name}} != nullptr && *{{name}} != QString("")) {
}{{/isByteArray}}{{/isDate}}{{/isDateTime}}{{/isPrimitiveType}}{{#isDate}}
if({{name}} != nullptr) {
toJsonValue(QString("{{baseName}}"), {{name}}, obj, QString("{{complexType}}"));
}{{/isDate}}{{#isByteArray}}
if({{name}} != nullptr) {
obj->insert("{{name}}", QJsonValue(*{{name}}));
}
{{/isString}}
{{/isContainer}}
{{#isListContainer}}
}{{/isByteArray}}{{#isDateTime}}
if({{name}} != nullptr) {
toJsonValue(QString("{{baseName}}"), {{name}}, obj, QString("{{complexType}}"));
}{{/isDateTime}}{{/isContainer}}{{#isContainer}}{{#isListContainer}}
if({{name}}->size() > 0){
QJsonArray {{name}}JsonArray;
toJsonArray((QList<void*>*){{name}}, &{{name}}JsonArray, "{{name}}", "{{items.baseType}}");
obj->insert("{{baseName}}", {{name}}JsonArray);
}
{{/isListContainer}}
{{#isMapContainer}}
{{^items.isContainer}}toJsonArray((QList<void*>*){{name}}, obj, "{{baseName}}", "{{complexType}}");{{/items.isContainer}}{{#items.isContainer}}
QJsonArray jarray;
for(auto items : *{{name}}){
QJsonObject jobj;
{{#items.isListContainer}}toJsonArray((QList<void*>*)items, &jobj, "{{baseName}}", "{{items.items.baseType}}");{{/items.isListContainer}}
{{#items.isMapContainer}}toJsonMap((QMap<QString, void*>*)items, &jobj, "{{baseName}}", "{{items.items.baseType}}");{{/items.isMapContainer}}
jarray.append(jobj.value("{{baseName}}"));
}
obj->insert("{{baseName}}", jarray);{{/items.isContainer}}
}{{/isListContainer}}{{#isMapContainer}}
if({{name}}->size() > 0){
QJsonObject {{name}}_jobj;
for(auto keyval : {{name}}->keys()){
toJsonValue(keyval, ((*{{name}})[keyval]), &{{name}}_jobj, "{{items.baseType}}");
}
obj->insert("{{baseName}}", {{name}}_jobj);
}
{{/isMapContainer}}
{{/complexType}}
{{^items.isContainer}}toJsonMap((QMap<QString, void*>*) {{name}}, obj, "{{baseName}}", "{{complexType}}");{{/items.isContainer}}{{#items.isContainer}}
QJsonObject mapobj;
for(auto itemkey : {{name}}->keys()){
QJsonObject jobj;
{{#items.isListContainer}}toJsonArray((QList<void*>*){{name}}->value(itemkey), &jobj, itemkey, "{{items.items.baseType}}");{{/items.isListContainer}}
{{#items.isMapContainer}}toJsonMap((QMap<QString, void*>*){{name}}->value(itemkey), &jobj, itemkey, "{{items.items.baseType}}");{{/items.isMapContainer}}
mapobj.insert(itemkey, jobj);
}
obj->insert("{{baseName}}", mapobj);{{/items.isContainer}}
}{{/isMapContainer}}{{/isContainer}}
{{/vars}}

return obj;
Expand Down
24 changes: 12 additions & 12 deletions samples/client/petstore/qt5cpp/PetStore/PetStore.pro
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,31 @@ TEMPLATE = app


SOURCES += main.cpp \
../client/Category.cpp \
../client/SWGCategory.cpp \
../client/SWGHelpers.cpp \
../client/SWGHttpRequest.cpp \
../client/Order.cpp \
../client/Pet.cpp \
../client/SWGOrder.cpp \
../client/SWGPet.cpp \
../client/SWGPetApi.cpp \
../client/SWGStoreApi.cpp \
../client/Tag.cpp \
../client/User.cpp \
../client/SWGTag.cpp \
../client/SWGUser.cpp \
../client/SWGUserApi.cpp \
../client/ApiResponse.cpp \
../client/SWGApiResponse.cpp \
PetApiTests.cpp

HEADERS += \
../client/Category.h \
../client/SWGCategory.h \
../client/SWGHelpers.h \
../client/SWGHttpRequest.h \
../client/SWGObject.h \
../client/Order.h \
../client/Pet.h \
../client/SWGOrder.h \
../client/SWGPet.h \
../client/SWGPetApi.h \
../client/SWGStoreApi.h \
../client/Tag.h \
../client/User.h \
../client/SWGTag.h \
../client/SWGUser.h \
../client/SWGUserApi.h \
PetApiTests.h \
../client/ApiResponse.h \
../client/SWGApiResponse.h \
../client/SWGModelFactory.h
10 changes: 8 additions & 2 deletions samples/client/petstore/qt5cpp/client/SWGApiResponse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ SWGApiResponse::init() {
void
SWGApiResponse::cleanup() {

if(type != nullptr) {
if(type != nullptr) {
delete type;
}
if(message != nullptr) {
if(message != nullptr) {
delete message;
}
}
Expand All @@ -68,8 +68,11 @@ SWGApiResponse::fromJson(QString &json) {
void
SWGApiResponse::fromJsonObject(QJsonObject &pJson) {
::Swagger::setValue(&code, pJson["code"], "qint32", "");

::Swagger::setValue(&type, pJson["type"], "QString", "QString");

::Swagger::setValue(&message, pJson["message"], "QString", "QString");

}

QString
Expand All @@ -85,12 +88,15 @@ SWGApiResponse::asJson ()
QJsonObject*
SWGApiResponse::asJsonObject() {
QJsonObject* obj = new QJsonObject();

if(m_code_isSet){
obj->insert("code", QJsonValue(code));
}

if(type != nullptr && *type != QString("")){
toJsonValue(QString("type"), type, obj, QString("QString"));
}

if(message != nullptr && *message != QString("")){
toJsonValue(QString("message"), message, obj, QString("QString"));
}
Expand Down
6 changes: 5 additions & 1 deletion samples/client/petstore/qt5cpp/client/SWGCategory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ SWGCategory::init() {
void
SWGCategory::cleanup() {

if(name != nullptr) {
if(name != nullptr) {
delete name;
}
}
Expand All @@ -63,7 +63,9 @@ SWGCategory::fromJson(QString &json) {
void
SWGCategory::fromJsonObject(QJsonObject &pJson) {
::Swagger::setValue(&id, pJson["id"], "qint64", "");

::Swagger::setValue(&name, pJson["name"], "QString", "QString");

}

QString
Expand All @@ -79,9 +81,11 @@ SWGCategory::asJson ()
QJsonObject*
SWGCategory::asJsonObject() {
QJsonObject* obj = new QJsonObject();

if(m_id_isSet){
obj->insert("id", QJsonValue(id));
}

if(name != nullptr && *name != QString("")){
toJsonValue(QString("name"), name, obj, QString("QString"));
}
Expand Down
Loading

0 comments on commit 0bf430a

Please sign in to comment.