From 5a1fa6ee65fc157c52fea545f76280b898322fe9 Mon Sep 17 00:00:00 2001 From: Tony Tam Date: Tue, 12 May 2015 05:56:12 -0400 Subject: [PATCH] added qt5 c++ templates --- .../codegen/languages/Qt5CPPGenerator.java | 306 ++++++++++++++++++ .../src/main/resources/qt5cpp/HttpRequest.cpp | 297 +++++++++++++++++ .../src/main/resources/qt5cpp/HttpRequest.h | 76 +++++ .../main/resources/qt5cpp/api-body.mustache | 107 ++++++ .../main/resources/qt5cpp/api-header.mustache | 34 ++ .../resources/qt5cpp/helpers-body.mustache | 161 +++++++++ .../resources/qt5cpp/helpers-header.mustache | 16 + .../main/resources/qt5cpp/model-body.mustache | 109 +++++++ .../resources/qt5cpp/model-header.mustache | 47 +++ .../src/main/resources/qt5cpp/model.mustache | 58 ++++ .../resources/qt5cpp/modelFactory.mustache | 18 ++ .../src/main/resources/qt5cpp/object.mustache | 24 ++ 12 files changed, 1253 insertions(+) create mode 100644 modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/Qt5CPPGenerator.java create mode 100644 modules/swagger-codegen/src/main/resources/qt5cpp/HttpRequest.cpp create mode 100644 modules/swagger-codegen/src/main/resources/qt5cpp/HttpRequest.h create mode 100644 modules/swagger-codegen/src/main/resources/qt5cpp/api-body.mustache create mode 100644 modules/swagger-codegen/src/main/resources/qt5cpp/api-header.mustache create mode 100644 modules/swagger-codegen/src/main/resources/qt5cpp/helpers-body.mustache create mode 100644 modules/swagger-codegen/src/main/resources/qt5cpp/helpers-header.mustache create mode 100644 modules/swagger-codegen/src/main/resources/qt5cpp/model-body.mustache create mode 100644 modules/swagger-codegen/src/main/resources/qt5cpp/model-header.mustache create mode 100644 modules/swagger-codegen/src/main/resources/qt5cpp/model.mustache create mode 100644 modules/swagger-codegen/src/main/resources/qt5cpp/modelFactory.mustache create mode 100644 modules/swagger-codegen/src/main/resources/qt5cpp/object.mustache diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/Qt5CPPGenerator.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/Qt5CPPGenerator.java new file mode 100644 index 00000000000..b3adeb19a32 --- /dev/null +++ b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/Qt5CPPGenerator.java @@ -0,0 +1,306 @@ +package com.wordnik.swagger.codegen.languages; + +import com.wordnik.swagger.codegen.*; +import com.wordnik.swagger.util.Json; +import com.wordnik.swagger.models.properties.*; + +import java.util.*; +import java.io.File; + +public class Qt5CPPGenerator extends DefaultCodegen implements CodegenConfig { + protected Set foundationClasses = new HashSet(); + + // source folder where to write the files + protected String sourceFolder = "client"; + protected String apiVersion = "1.0.0"; + protected final String PREFIX = "SWG"; + protected Map namespaces = new HashMap(); + protected Set systemIncludes = new HashSet(); + + /** + * Configures the type of generator. + * + * @return the CodegenType for this generator + * @see com.wordnik.swagger.codegen.CodegenType + */ + public CodegenType getTag() { + return CodegenType.CLIENT; + } + + /** + * Configures a friendly name for the generator. This will be used by the generator + * to select the library with the -l flag. + * + * @return the friendly name for the generator + */ + public String getName() { + return "qt5cpp"; + } + + /** + * Returns human-friendly help for the generator. Provide the consumer with help + * tips, parameters here + * + * @return A string value for the help message + */ + public String getHelp() { + return "Generates a qt5 C++ client library."; + } + + public Qt5CPPGenerator() { + super(); + + // set the output folder here + outputFolder = "generated-code/qt5cpp"; + + /** + * Models. You can write model files using the modelTemplateFiles map. + * if you want to create one template for file, you can do so here. + * for multiple files for model, just put another entry in the `modelTemplateFiles` with + * a different extension + */ + modelTemplateFiles.put( + "model-header.mustache", + ".h"); + + modelTemplateFiles.put( + "model-body.mustache", + ".cpp"); + + /** + * Api classes. You can write classes for each Api file with the apiTemplateFiles map. + * as with models, add multiple entries with different extensions for multiple files per + * class + */ + apiTemplateFiles.put( + "api-header.mustache", // the template to use + ".h"); // the extension for each file to write + + apiTemplateFiles.put( + "api-body.mustache", // the template to use + ".cpp"); // the extension for each file to write + + /** + * Template Location. This is the location which templates will be read from. The generator + * will use the resource stream to attempt to read the templates. + */ + templateDir = "qt5cpp"; + + /** + * Reserved words. Override this with reserved words specific to your language + */ + reservedWords = new HashSet ( + Arrays.asList( + "sample1", // replace with static values + "sample2") + ); + + /** + * Additional Properties. These values can be passed to the templates and + * are available in models, apis, and supporting files + */ + additionalProperties.put("apiVersion", apiVersion); + additionalProperties().put("prefix", PREFIX); + + /** + * Language Specific Primitives. These types will not trigger imports by + * the client generator + */ + languageSpecificPrimitives = new HashSet( + Arrays.asList( + "bool", + "qint32", + "qint64") + ); + + supportingFiles.add(new SupportingFile("helpers-header.mustache", sourceFolder, PREFIX + "Helpers.h")); + supportingFiles.add(new SupportingFile("helpers-body.mustache", sourceFolder, PREFIX + "Helpers.cpp")); + supportingFiles.add(new SupportingFile("HttpRequest.h", sourceFolder, PREFIX + "HttpRequest.h")); + supportingFiles.add(new SupportingFile("HttpRequest.cpp", sourceFolder, PREFIX + "HttpRequest.cpp")); + supportingFiles.add(new SupportingFile("modelFactory.mustache", sourceFolder, PREFIX + "ModelFactory.h")); + supportingFiles.add(new SupportingFile("object.mustache", sourceFolder, PREFIX + "Object.h")); + + super.typeMapping = new HashMap(); + + typeMapping.put("Date", "QDate"); + typeMapping.put("DateTime", "QDateTime"); + typeMapping.put("string", "QString"); + typeMapping.put("integer", "qint32"); + typeMapping.put("long", "qint64"); + typeMapping.put("boolean", "bool"); + typeMapping.put("array", "QList"); + typeMapping.put("map", "QMap"); + // typeMapping.put("number", "Long"); + typeMapping.put("object", PREFIX + "Object"); + + importMapping = new HashMap(); + + namespaces = new HashMap (); + + foundationClasses.add("QString"); + + systemIncludes.add("QString"); + systemIncludes.add("QList"); + } + + @Override + public String toModelImport(String name) { + if(namespaces.containsKey(name)) { + return "using " + namespaces.get(name) + ";"; + } + else if(systemIncludes.contains(name)) { + return "#include <" + name + ">"; + } + return "#include \"" + name + ".h\""; + } + + /** + * Escapes a reserved word as defined in the `reservedWords` array. Handle escaping + * those terms here. This logic is only called if a variable matches the reseved words + * + * @return the escaped term + */ + @Override + public String escapeReservedWord(String name) { + return "_" + name; // add an underscore to the name + } + + /** + * Location to write model files. You can use the modelPackage() as defined when the class is + * instantiated + */ + public String modelFileFolder() { + return outputFolder + "/" + sourceFolder + "/" + modelPackage().replace('.', File.separatorChar); + } + + /** + * Location to write api files. You can use the apiPackage() as defined when the class is + * instantiated + */ + @Override + public String apiFileFolder() { + return outputFolder + "/" + sourceFolder + "/" + apiPackage().replace('.', File.separatorChar); + } + + @Override + public String toModelFilename(String name) { + return PREFIX + initialCaps(name); + } + + @Override + public String toApiFilename(String name) { + return PREFIX + initialCaps(name) + "Api"; + } + + /** + * Optional - type declaration. This is a String which is used by the templates to instantiate your + * types. There is typically special handling for different property types + * + * @return a string value used as the `dataType` field for model templates, `returnType` for api templates + */ + @Override + public String getTypeDeclaration(Property p) { + String swaggerType = getSwaggerType(p); + + if(p instanceof ArrayProperty) { + ArrayProperty ap = (ArrayProperty) p; + Property inner = ap.getItems(); + return getSwaggerType(p) + "<" + getTypeDeclaration(inner) + ">*"; + } + else if (p instanceof MapProperty) { + MapProperty mp = (MapProperty) p; + Property inner = mp.getAdditionalProperties(); + return getSwaggerType(p) + "*"; + } + if(foundationClasses.contains(swaggerType)) + return swaggerType + "*"; + else if(languageSpecificPrimitives.contains(swaggerType)) + return toModelName(swaggerType); + else + return swaggerType + "*"; + } + + @Override + public String toDefaultValue(Property p) { + if(p instanceof StringProperty) + return "new QString(\"\")"; + else if (p instanceof BooleanProperty) + return "false"; + else if(p instanceof DateProperty) + return "NULL"; + else if(p instanceof DateTimeProperty) + return "NULL"; + else if (p instanceof DoubleProperty) + return "0.0"; + else if (p instanceof FloatProperty) + return "0.0f"; + else if (p instanceof IntegerProperty) + return "0"; + else if (p instanceof LongProperty) + return "0L"; + else if (p instanceof DecimalProperty) + return "0.0"; + else if (p instanceof MapProperty) { + MapProperty ap = (MapProperty) p; + String inner = getSwaggerType(ap.getAdditionalProperties()); + return "NULL"; + } + else if (p instanceof ArrayProperty) { + ArrayProperty ap = (ArrayProperty) p; + String inner = getSwaggerType(ap.getItems()); + if(!languageSpecificPrimitives.contains(inner)) { + inner += "*"; + } + return "new QList<" + inner + ">()"; + } + // else + if(p instanceof RefProperty) { + RefProperty rp = (RefProperty) p; + return "new " + toModelName(rp.getSimpleRef()) + "()"; + } + return "NULL"; + } + + + /** + * Optional - swagger type conversion. This is used to map swagger types in a `Property` into + * either language specific types via `typeMapping` or into complex models if there is not a mapping. + * + * @return a string value of the type or complex model for this property + * @see com.wordnik.swagger.models.properties.Property + */ + @Override + public String getSwaggerType(Property p) { + String swaggerType = super.getSwaggerType(p); + String type = null; + if(typeMapping.containsKey(swaggerType)) { + type = typeMapping.get(swaggerType); + if(languageSpecificPrimitives.contains(type)) + return toModelName(type); + if(foundationClasses.contains(type)) + return type; + } + else + type = swaggerType; + return toModelName(type); + } + + @Override + public String toModelName(String type) { + if(typeMapping.keySet().contains(type) || + typeMapping.values().contains(type) || + importMapping.values().contains(type) || + defaultIncludes.contains(type) || + languageSpecificPrimitives.contains(type)) { + return type; + } + else { + return PREFIX + Character.toUpperCase(type.charAt(0)) + type.substring(1); + } + } + + @Override + public String toApiName(String type) { + return PREFIX + Character.toUpperCase(type.charAt(0)) + type.substring(1) + "Api"; + } +} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/qt5cpp/HttpRequest.cpp b/modules/swagger-codegen/src/main/resources/qt5cpp/HttpRequest.cpp new file mode 100644 index 00000000000..fed94e8dddb --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/qt5cpp/HttpRequest.cpp @@ -0,0 +1,297 @@ +#include "SWGHttpRequest.h" +#include +#include +#include +#include + + +HttpRequestInput::HttpRequestInput() { + initialize(); +} + +HttpRequestInput::HttpRequestInput(QString v_url_str, QString v_http_method) { + initialize(); + url_str = v_url_str; + http_method = v_http_method; +} + +void HttpRequestInput::initialize() { + var_layout = NOT_SET; + url_str = ""; + http_method = "GET"; +} + +void HttpRequestInput::add_var(QString key, QString value) { + vars[key] = value; +} + +void HttpRequestInput::add_file(QString variable_name, QString local_filename, QString request_filename, QString mime_type) { + HttpRequestInputFileElement file; + file.variable_name = variable_name; + file.local_filename = local_filename; + file.request_filename = request_filename; + file.mime_type = mime_type; + files.append(file); +} + + +HttpRequestWorker::HttpRequestWorker(QObject *parent) + : QObject(parent), manager(NULL) +{ + qsrand(QDateTime::currentDateTime().toTime_t()); + + manager = new QNetworkAccessManager(this); + connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(on_manager_finished(QNetworkReply*))); +} + +HttpRequestWorker::~HttpRequestWorker() { +} + +QString HttpRequestWorker::http_attribute_encode(QString attribute_name, QString input) { + // result structure follows RFC 5987 + bool need_utf_encoding = false; + QString result = ""; + QByteArray input_c = input.toLocal8Bit(); + char c; + for (int i = 0; i < input_c.length(); i++) { + c = input_c.at(i); + if (c == '\\' || c == '/' || c == '\0' || c < ' ' || c > '~') { + // ignore and request utf-8 version + need_utf_encoding = true; + } + else if (c == '"') { + result += "\\\""; + } + else { + result += c; + } + } + + if (result.length() == 0) { + need_utf_encoding = true; + } + + if (!need_utf_encoding) { + // return simple version + return QString("%1=\"%2\"").arg(attribute_name, result); + } + + QString result_utf8 = ""; + for (int i = 0; i < input_c.length(); i++) { + c = input_c.at(i); + if ( + (c >= '0' && c <= '9') + || (c >= 'A' && c <= 'Z') + || (c >= 'a' && c <= 'z') + ) { + result_utf8 += c; + } + else { + result_utf8 += "%" + QString::number(static_cast(input_c.at(i)), 16).toUpper(); + } + } + + // return enhanced version with UTF-8 support + return QString("%1=\"%2\"; %1*=utf-8''%3").arg(attribute_name, result, result_utf8); +} + +void HttpRequestWorker::execute(HttpRequestInput *input) { + + // reset variables + + QByteArray request_content = ""; + response = ""; + error_type = QNetworkReply::NoError; + error_str = ""; + + + // decide on the variable layout + + if (input->files.length() > 0) { + input->var_layout = MULTIPART; + } + if (input->var_layout == NOT_SET) { + input->var_layout = input->http_method == "GET" || input->http_method == "HEAD" ? ADDRESS : URL_ENCODED; + } + + + // prepare request content + + QString boundary = ""; + + if (input->var_layout == ADDRESS || input->var_layout == URL_ENCODED) { + // variable layout is ADDRESS or URL_ENCODED + + if (input->vars.count() > 0) { + bool first = true; + foreach (QString key, input->vars.keys()) { + if (!first) { + request_content.append("&"); + } + first = false; + + request_content.append(QUrl::toPercentEncoding(key)); + request_content.append("="); + request_content.append(QUrl::toPercentEncoding(input->vars.value(key))); + } + + if (input->var_layout == ADDRESS) { + input->url_str += "?" + request_content; + request_content = ""; + } + } + } + else { + // variable layout is MULTIPART + + boundary = "__-----------------------" + + QString::number(QDateTime::currentDateTime().toTime_t()) + + QString::number(qrand()); + QString boundary_delimiter = "--"; + QString new_line = "\r\n"; + + // add variables + foreach (QString key, input->vars.keys()) { + // add boundary + request_content.append(boundary_delimiter); + request_content.append(boundary); + request_content.append(new_line); + + // add header + request_content.append("Content-Disposition: form-data; "); + request_content.append(http_attribute_encode("name", key)); + request_content.append(new_line); + request_content.append("Content-Type: text/plain"); + request_content.append(new_line); + + // add header to body splitter + request_content.append(new_line); + + // add variable content + request_content.append(input->vars.value(key)); + request_content.append(new_line); + } + + // add files + for (QList::iterator file_info = input->files.begin(); file_info != input->files.end(); file_info++) { + QFileInfo fi(file_info->local_filename); + + // ensure necessary variables are available + if ( + file_info->local_filename == NULL || file_info->local_filename.isEmpty() + || file_info->variable_name == NULL || file_info->variable_name.isEmpty() + || !fi.exists() || !fi.isFile() || !fi.isReadable() + ) { + // silent abort for the current file + continue; + } + + QFile file(file_info->local_filename); + if (!file.open(QIODevice::ReadOnly)) { + // silent abort for the current file + continue; + } + + // ensure filename for the request + if (file_info->request_filename == NULL || file_info->request_filename.isEmpty()) { + file_info->request_filename = fi.fileName(); + if (file_info->request_filename.isEmpty()) { + file_info->request_filename = "file"; + } + } + + // add boundary + request_content.append(boundary_delimiter); + request_content.append(boundary); + request_content.append(new_line); + + // add header + request_content.append(QString("Content-Disposition: form-data; %1; %2").arg( + http_attribute_encode("name", file_info->variable_name), + http_attribute_encode("filename", file_info->request_filename) + )); + request_content.append(new_line); + + if (file_info->mime_type != NULL && !file_info->mime_type.isEmpty()) { + request_content.append("Content-Type: "); + request_content.append(file_info->mime_type); + request_content.append(new_line); + } + + request_content.append("Content-Transfer-Encoding: binary"); + request_content.append(new_line); + + // add header to body splitter + request_content.append(new_line); + + // add file content + request_content.append(file.readAll()); + request_content.append(new_line); + + file.close(); + } + + // add end of body + request_content.append(boundary_delimiter); + request_content.append(boundary); + request_content.append(boundary_delimiter); + } + + if(input->request_body.size() > 0) { + qDebug() << "got a request body"; + request_content.clear(); + request_content.append(input->request_body); + } + // prepare connection + + QNetworkRequest request = QNetworkRequest(QUrl(input->url_str)); + request.setRawHeader("User-Agent", "Swagger-Client"); + foreach(QString key, input->headers.keys()) { + request.setRawHeader(key.toStdString().c_str(), input->headers.value(key).toStdString().c_str()); + } + + if (request_content.size() > 0) { + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + } + else if (input->var_layout == URL_ENCODED) { + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); + } + else if (input->var_layout == MULTIPART) { + request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data; boundary=" + boundary); + } + + if (input->http_method == "GET") { + manager->get(request); + } + else if (input->http_method == "POST") { + manager->post(request, request_content); + } + else if (input->http_method == "PUT") { + manager->put(request, request_content); + } + else if (input->http_method == "HEAD") { + manager->head(request); + } + else if (input->http_method == "DELETE") { + manager->deleteResource(request); + } + else { + QBuffer buff(&request_content); + manager->sendCustomRequest(request, input->http_method.toLatin1(), &buff); + } + +} + +void HttpRequestWorker::on_manager_finished(QNetworkReply *reply) { + error_type = reply->error(); + if (error_type == QNetworkReply::NoError) { + response = reply->readAll(); + } + else { + error_str = reply->errorString(); + } + + reply->deleteLater(); + + emit on_execution_finished(this); +} diff --git a/modules/swagger-codegen/src/main/resources/qt5cpp/HttpRequest.h b/modules/swagger-codegen/src/main/resources/qt5cpp/HttpRequest.h new file mode 100644 index 00000000000..260ccb20679 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/qt5cpp/HttpRequest.h @@ -0,0 +1,76 @@ +/** + * Based on http://www.creativepulse.gr/en/blog/2014/restful-api-requests-using-qt-cpp-for-linux-mac-osx-ms-windows + * By Alex Stylianos + * + **/ + +#ifndef HTTPREQUESTWORKER_H +#define HTTPREQUESTWORKER_H + +#include +#include +#include +#include +#include + + +enum HttpRequestVarLayout {NOT_SET, ADDRESS, URL_ENCODED, MULTIPART}; + + +class HttpRequestInputFileElement { + +public: + QString variable_name; + QString local_filename; + QString request_filename; + QString mime_type; + +}; + + +class HttpRequestInput { + +public: + QString url_str; + QString http_method; + HttpRequestVarLayout var_layout; + QMap vars; + QMap headers; + QList files; + QByteArray request_body; + + HttpRequestInput(); + HttpRequestInput(QString v_url_str, QString v_http_method); + void initialize(); + void add_var(QString key, QString value); + void add_file(QString variable_name, QString local_filename, QString request_filename, QString mime_type); + +}; + + +class HttpRequestWorker : public QObject { + Q_OBJECT + +public: + QByteArray response; + QNetworkReply::NetworkError error_type; + QString error_str; + + explicit HttpRequestWorker(QObject *parent = 0); + virtual ~HttpRequestWorker(); + + QString http_attribute_encode(QString attribute_name, QString input); + void execute(HttpRequestInput *input); + +signals: + void on_execution_finished(HttpRequestWorker *worker); + +private: + QNetworkAccessManager *manager; + +private slots: + void on_manager_finished(QNetworkReply *reply); + +}; + +#endif // HTTPREQUESTWORKER_H diff --git a/modules/swagger-codegen/src/main/resources/qt5cpp/api-body.mustache b/modules/swagger-codegen/src/main/resources/qt5cpp/api-body.mustache new file mode 100644 index 00000000000..a7a1d2646dd --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/qt5cpp/api-body.mustache @@ -0,0 +1,107 @@ +#include "{{classname}}.h" +#include "{{prefix}}Helpers.h" + +#include +#include + +namespace Swagger { +{{classname}}::{{classname}}() {} + +{{classname}}::~{{classname}}() {} + +{{classname}}::{{classname}}(QString host, QString basePath) { + this->host = host; + this->basePath = basePath; +} + +{{#operations}} +{{#operation}} +void +{{classname}}::{{nickname}}({{#allParams}}{{dataType}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) { + QString fullPath; + fullPath.append(this->host).append(this->basePath).append("{{path}}"); + + {{#pathParams}} + QString {{paramName}}PathParam("{"); {{paramName}}PathParam.append("{{paramName}}").append("}"); + fullPath.replace({{paramName}}PathParam, stringValue({{paramName}})); + {{/pathParams}} + + {{#queryParams}}if(fullPath.compare("?") > 0) fullPath.append("?"); + else fullPath.append("&"); + fullPath.append(QUrl::toPercentEncoding("{{paramName}}")) + .append("=") + .append(QUrl::toPercentEncoding(stringValue({{paramName}}))); + {{/queryParams}} + + // qDebug() << fullPath; + + HttpRequestWorker *worker = new HttpRequestWorker(); + HttpRequestInput input(fullPath, "{{httpMethod}}"); + + {{#bodyParams}} + // body + input.request_body.append({{paramName}}.asJson()); + {{/bodyParams}} + + {{#headerParams}} + input.headers + {{/headerParams}} + + connect(worker, + &HttpRequestWorker::on_execution_finished, + this, + &{{classname}}::{{nickname}}Callback); + + worker->execute(&input); +} + +void +{{classname}}::{{nickname}}Callback(HttpRequestWorker * worker) { + QString msg; + if (worker->error_type == QNetworkReply::NoError) { + msg = QString("Success! %1 bytes").arg(worker->response.length()); + } + else { + msg = "Error: " + worker->error_str; + } + + // return type: {{{returnType}}} + + {{#returnType}} + {{#isListContainer}} + {{{returnType}}} output = {{{defaultResponse}}}; + QString json(worker->response); + QByteArray array (json.toStdString().c_str()); + QJsonDocument doc = QJsonDocument::fromJson(array); + QJsonArray jsonArray = doc.array(); + + foreach(QJsonValue obj, jsonArray) { + {{returnBaseType}}* o = new {{returnBaseType}}(); + QJsonObject jv = obj.toObject(); + QJsonObject * ptr = (QJsonObject*)&jv; + o->fromJsonObject(*ptr); + output->append(o); + } + + + // void toJsonArray(QList* value, QJsonArray* output, QString innerName, QString innerType); + {{/isListContainer}} + + {{^isListContainer}}{{#returnTypeIsPrimitive}} + {{returnType}} output; // TODO + + {{/returnTypeIsPrimitive}} + {{^returnTypeIsPrimitive}}QString json(worker->response); + {{returnType}} output = new {{returnBaseType}}(&json); + + {{/returnTypeIsPrimitive}} + {{/isListContainer}}{{/returnType}} + + worker->deleteLater(); + + {{#returnType}}emit {{nickname}}Signal(output);{{/returnType}} + {{^returnType}}emit {{nickname}}Signal();{{/returnType}} +} +{{/operation}} +{{/operations}} +} /* namespace Swagger */ diff --git a/modules/swagger-codegen/src/main/resources/qt5cpp/api-header.mustache b/modules/swagger-codegen/src/main/resources/qt5cpp/api-header.mustache new file mode 100644 index 00000000000..364dc9b8e47 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/qt5cpp/api-header.mustache @@ -0,0 +1,34 @@ +#ifndef _SWG_{{classname}}_H_ +#define _SWG_{{classname}}_H_ + +#include "{{prefix}}HttpRequest.h" + +{{#imports}}{{{import}}} +{{/imports}} + +#include + +namespace Swagger { + +class {{classname}}: public QObject { + Q_OBJECT + +public: + {{classname}}(); + {{classname}}(QString host, QString basePath); + ~{{classname}}(); + + QString host; + QString basePath; + + {{#operations}}{{#operation}}void {{nickname}}({{#allParams}}{{dataType}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}); + {{/operation}}{{/operations}} +private: + {{#operations}}{{#operation}}void {{nickname}}Callback (HttpRequestWorker * worker); + {{/operation}}{{/operations}} +signals: + {{#operations}}{{#operation}}void {{nickname}}Signal({{#returnType}}{{{returnType}}} summary{{/returnType}}); + {{/operation}}{{/operations}} +}; +} +#endif \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/qt5cpp/helpers-body.mustache b/modules/swagger-codegen/src/main/resources/qt5cpp/helpers-body.mustache new file mode 100644 index 00000000000..01e205a0773 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/qt5cpp/helpers-body.mustache @@ -0,0 +1,161 @@ +#include "SWGHelpers.h" +#include "SWGModelFactory.h" +#include "SWGObject.h" +#import +#import +#import + +namespace Swagger { + +void +setValue(void* value, QJsonValue obj, QString type, QString complexType) { + if(value == NULL) { + // can't set value with a null pointer + return; + } + if(QStringLiteral("bool").compare(type) == 0) { + bool * val = static_cast(value); + *val = obj.toBool(); + } + else if(QStringLiteral("qint32").compare(type) == 0) { + qint32 *val = static_cast(value); + *val = obj.toInt(); + } + else if(QStringLiteral("qint64").compare(type) == 0) { + qint64 *val = static_cast(value); + *val = obj.toVariant().toLongLong(); + } + else if (QStringLiteral("QString").compare(type) == 0) { + QString **val = static_cast(value); + + if(val != NULL) { + if(!obj.isNull()) { + // create a new value and return + delete *val; + *val = new QString(obj.toString()); + return; + } + else { + // set target to NULL + delete *val; + *val = NULL; + } + } + else { + qDebug() << "Can't set value because the target pointer is NULL"; + } + } + else if(type.startsWith("SWG") && obj.isObject()) { + // complex type + QJsonObject jsonObj = obj.toObject(); + SWGObject * so = (SWGObject*)Swagger::create(type); + if(so != NULL) { + so->fromJsonObject(jsonObj); + SWGObject **val = static_cast(value); + delete *val; + *val = so; + } + } + else if(type.startsWith("QList") && QString("").compare(complexType) != 0 && obj.isArray()) { + // list of values + QList* output = new QList(); + QJsonArray arr = obj.toArray(); + foreach (const QJsonValue & jval, arr) { + if(complexType.startsWith("SWG")) { + // it's an object + SWGObject * val = (SWGObject*)create(complexType); + QJsonObject t = jval.toObject(); + + val->fromJsonObject(t); + output->append(val); + } + else { + // primitives + if(QStringLiteral("qint32").compare(complexType) == 0) { + qint32 val; + setValue(&val, jval, QStringLiteral("qint32"), QStringLiteral("")); + output->append((void*)&val); + } + else if(QStringLiteral("qint64").compare(complexType) == 0) { + qint64 val; + setValue(&val, jval, QStringLiteral("qint64"), QStringLiteral("")); + output->append((void*)&val); + } + else if(QStringLiteral("bool").compare(complexType) == 0) { + bool val; + setValue(&val, jval, QStringLiteral("bool"), QStringLiteral("")); + output->append((void*)&val); + } + } + } + QList **val = static_cast**>(value); + delete *val; + *val = output; + } +} + +void +toJsonValue(QString name, void* value, QJsonObject* output, QString type) { + if(value == NULL) { + return; + } + if(type.startsWith("SWG")) { + SWGObject *swgObject = reinterpret_cast(value); + if(swgObject != NULL) { + QJsonObject* o = (*swgObject).asJsonObject(); + if(name != NULL) { + output->insert(name, *o); + delete o; + } + else { + output->empty(); + foreach(QString key, o->keys()) { + output->insert(key, o->value(key)); + } + } + } + } + else if(QStringLiteral("QString").compare(type) == 0) { + QString* str = static_cast(value); + output->insert(name, QJsonValue(*str)); + } + else if(QStringLiteral("qint32").compare(type) == 0) { + qint32* str = static_cast(value); + output->insert(name, QJsonValue(*str)); + } + else if(QStringLiteral("qint64").compare(type) == 0) { + qint64* str = static_cast(value); + output->insert(name, QJsonValue(*str)); + } + else if(QStringLiteral("bool").compare(type) == 0) { + bool* str = static_cast(value); + output->insert(name, QJsonValue(*str)); + } +} + +void +toJsonArray(QList* value, QJsonArray* output, QString innerName, QString innerType) { + foreach(void* obj, *value) { + QJsonObject element; + + toJsonValue(NULL, obj, &element, innerType); + output->append(element); + } +} + +QString +stringValue(QString* value) { + QString* str = static_cast(value); + return QString(*str); +} + +QString +stringValue(qint32 value) { + return QString::number(value); +} + +QString +stringValue(bool value) { + return QString(value ? "true" : "false"); +} +} /* namespace Swagger */ diff --git a/modules/swagger-codegen/src/main/resources/qt5cpp/helpers-header.mustache b/modules/swagger-codegen/src/main/resources/qt5cpp/helpers-header.mustache new file mode 100644 index 00000000000..988e6480da8 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/qt5cpp/helpers-header.mustache @@ -0,0 +1,16 @@ +#ifndef SWGHELPERS_H +#define SWGHELPERS_H + +#include + +namespace Swagger { + void setValue(void* value, QJsonValue obj, QString type, QString complexType); + void toJsonArray(QList* value, QJsonArray* output, QString innerName, QString innerType); + void toJsonValue(QString name, void* value, QJsonObject* output, QString type); + bool isCompatibleJsonValue(QString type); + QString stringValue(QString* value); + QString stringValue(qint32 value); + QString stringValue(bool value); +} + +#endif // SWGHELPERS_H diff --git a/modules/swagger-codegen/src/main/resources/qt5cpp/model-body.mustache b/modules/swagger-codegen/src/main/resources/qt5cpp/model-body.mustache new file mode 100644 index 00000000000..705cb852108 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/qt5cpp/model-body.mustache @@ -0,0 +1,109 @@ +{{#models}}{{#model}} +#include "{{classname}}.h" + +#include "SWGHelpers.h" + +#include +#include +#include +#include + +namespace Swagger { + + +{{classname}}::{{classname}}(QString* json) { + init(); + this->fromJson(*json); +} + +{{classname}}::{{classname}}() { + init(); +} + +{{classname}}::~{{classname}}() { + this->cleanup(); +} + +void +{{classname}}::init() { + {{#vars}}{{name}} = {{{defaultValue}}}; + {{/vars}} +} + +void +{{classname}}::cleanup() { + {{#vars}}{{#complexType}}if({{name}} != NULL) { + {{#isContainer}}QList<{{complexType}}*>* arr = {{name}}; + foreach({{complexType}}* o, *arr) { + delete o; + } + {{/isContainer}}delete {{name}}; + }{{/complexType}} + {{/vars}} +} + +{{classname}}* +{{classname}}::fromJson(QString &json) { + QByteArray array (json.toStdString().c_str()); + QJsonDocument doc = QJsonDocument::fromJson(array); + QJsonObject jsonObject = doc.object(); + this->fromJsonObject(jsonObject); + return this; +} + +void +{{classname}}::fromJsonObject(QJsonObject &pJson) { + {{#vars}}setValue(&{{name}}, pJson["{{name}}"], "{{baseType}}", "{{complexType}}"); + {{/vars}} +} + +QString +{{classname}}::asJson () +{ + QJsonObject* obj = this->asJsonObject(); + + QJsonDocument doc(*obj); + QByteArray bytes = doc.toJson(); + return QString(bytes); +} + +QJsonObject* +{{classname}}::asJsonObject() { + QJsonObject* obj = new QJsonObject(); + {{#vars}}{{#complexType}} + {{^isContainer}}{{#complexType}} + toJsonValue(QString("{{name}}"), {{name}}, obj, QString("{{complexType}}")); + {{/complexType}}{{^complexType}} + else if({{name}} != NULL && *{{name}} != NULL) { + obj->insert("{{name}}", QJsonValue(*{{name}})); + }{{/complexType}} + {{/isContainer}}{{#isContainer}} + QList<{{complexType}}*>* {{name}}List = {{name}}; + QJsonArray {{name}}JsonArray; + toJsonArray((QList*){{name}}, &{{name}}JsonArray, "{{name}}", "{{complexType}}"); + + obj->insert("{{name}}", {{name}}JsonArray); + {{/isContainer}} + {{/complexType}}{{^complexType}}obj->insert("{{name}}", QJsonValue({{name}}));{{/complexType}} + {{/vars}} + + return obj; +} + +{{#vars}} +{{{datatype}}} +{{classname}}::{{getter}}() { + return {{name}}; +} +void +{{classname}}::{{setter}}({{{datatype}}} {{name}}) { + this->{{name}} = {{name}}; +} + +{{/vars}} + + +} /* namespace Swagger */ + +{{/model}} +{{/models}} diff --git a/modules/swagger-codegen/src/main/resources/qt5cpp/model-header.mustache b/modules/swagger-codegen/src/main/resources/qt5cpp/model-header.mustache new file mode 100644 index 00000000000..7b0b6cdcc1b --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/qt5cpp/model-header.mustache @@ -0,0 +1,47 @@ +{{#models}}{{#model}}/* + * {{classname}}.h + * + * {{description}} + */ + +#ifndef {{classname}}_H_ +#define {{classname}}_H_ + +#include + +{{/model}}{{/models}} +{{#imports}}{{{import}}} +{{/imports}} + +#include "SWGObject.h" + +{{#models}}{{#model}} +namespace Swagger { + +class {{classname}}: public SWGObject { +public: + {{classname}}(); + {{classname}}(QString* json); + virtual ~{{classname}}(); + void init(); + void cleanup(); + + QString asJson (); + QJsonObject* asJsonObject(); + void fromJsonObject(QJsonObject &json); + {{classname}}* fromJson(QString &jsonString); + + {{#vars}}{{{datatype}}} {{getter}}(); + void {{setter}}({{{datatype}}} {{name}}); + {{/vars}} + +private: + {{#vars}}{{{datatype}}} {{name}}; + {{/vars}} +}; + +} /* namespace Swagger */ + +#endif /* {{classname}}_H_ */ +{{/model}} +{{/models}} diff --git a/modules/swagger-codegen/src/main/resources/qt5cpp/model.mustache b/modules/swagger-codegen/src/main/resources/qt5cpp/model.mustache new file mode 100644 index 00000000000..1a2a831f5ac --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/qt5cpp/model.mustache @@ -0,0 +1,58 @@ +{{#models}}{{#model}}/* + * {{classname}}.h + * + * {{description}} + */ + +#ifndef {{classname}}_H_ +#define {{classname}}_H_ + +#include +#include +#include +#include +#include "{{prefix}}Helpers.h" +#include "{{prefix}}Object.h" + +using namespace Tizen::Web::Json; + +{{/model}}{{/models}} +{{#imports}}{{{import}}} +{{/imports}} + +{{#models}}{{#model}} +namespace Swagger { + +class {{classname}}: public {{prefix}}Object { +public: + {{classname}}(); + {{classname}}(String* json); + virtual ~{{classname}}(); + + void init(); + + void cleanup(); + + String asJson (); + + JsonObject* asJsonObject(); + + void fromJsonObject(IJsonValue* json); + + {{classname}}* fromJson(String* obj); + + {{#vars}} + {{datatype}} {{getter}}(); + void {{setter}}({{datatype}} {{name}}); + {{/vars}} + +private: + {{#vars}}{{datatype}} {{name}}; + {{/vars}} +}; + +} /* namespace Swagger */ + +#endif /* {{classname}}_H_ */ +{{/model}} +{{/models}} diff --git a/modules/swagger-codegen/src/main/resources/qt5cpp/modelFactory.mustache b/modules/swagger-codegen/src/main/resources/qt5cpp/modelFactory.mustache new file mode 100644 index 00000000000..f3cd5c8e2f0 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/qt5cpp/modelFactory.mustache @@ -0,0 +1,18 @@ +#ifndef ModelFactory_H_ +#define ModelFactory_H_ + +{{#models}}{{#model}} +#include "{{classname}}.h"{{/model}}{{/models}} + +namespace Swagger { + void* + create(QString type) { + {{#models}}{{#model}}if(QString("{{classname}}").compare(type) == 0) { + return new {{classname}}(); + } + {{/model}}{{/models}} + return NULL; + } +} /* namespace Swagger */ + +#endif /* ModelFactory_H_ */ diff --git a/modules/swagger-codegen/src/main/resources/qt5cpp/object.mustache b/modules/swagger-codegen/src/main/resources/qt5cpp/object.mustache new file mode 100644 index 00000000000..62914cb5162 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/qt5cpp/object.mustache @@ -0,0 +1,24 @@ +#ifndef _{{prefix}}_OBJECT_H_ +#define _{{prefix}}_OBJECT_H_ + +#include + +class {{prefix}}Object { + public: + virtual QJsonObject* asJsonObject() { + return NULL; + } + virtual ~SWGObject() {} + virtual SWGObject* fromJson(QString &jsonString) { + Q_UNUSED(jsonString); + return NULL; + } + virtual void fromJsonObject(QJsonObject &json) { + Q_UNUSED(json); + } + virtual QString asJson() { + return QString(""); + } +}; + +#endif /* _{{prefix}}_OBJECT_H_ */