drogon/drogon_ctl/create_controller.cc

407 lines
15 KiB
C++
Raw Normal View History

2018-05-31 17:00:31 +08:00
/**
*
* @file
* @author An Tao
* @section LICENSE
*
* Copyright 2018, An Tao. All rights reserved.
* Use of this source code is governed by a MIT license
* that can be found in the License file.
*
* @section DESCRIPTION
*
*/
#include "create_controller.h"
#include "cmd.h"
#include <iostream>
#include <fstream>
#include <regex>
using namespace drogon_ctl;
void create_controller::handleCommand(std::vector<std::string> &parameters)
{
//std::cout<<"create!"<<std::endl;
2018-10-14 15:56:54 +08:00
ControllerType type = Simple;
for (auto iter = parameters.begin(); iter != parameters.end(); iter++)
{
2018-10-14 15:56:54 +08:00
if ((*iter)[0] == '-')
{
2018-10-14 15:56:54 +08:00
if (*iter == "-s" || (*iter == "--simple"))
{
parameters.erase(iter);
break;
}
2018-10-14 15:56:54 +08:00
else if (*iter == "-a" || *iter == "--api")
{
2018-10-14 15:56:54 +08:00
type = API;
parameters.erase(iter);
break;
}
2018-10-14 15:56:54 +08:00
else if (*iter == "-w" || *iter == "--websocket")
2018-08-22 14:27:45 +08:00
{
2018-10-14 15:56:54 +08:00
type = WebSocket;
2018-08-22 14:27:45 +08:00
parameters.erase(iter);
break;
}
2018-10-14 15:56:54 +08:00
else if (*iter == "-n" || *iter == "--namespace")
{
2018-10-14 15:56:54 +08:00
if (type == Simple)
break;
else
{
2018-10-14 15:56:54 +08:00
std::cout << ARGS_ERROR_STR << std::endl;
return;
}
}
else
{
2018-10-14 15:56:54 +08:00
std::cout << ARGS_ERROR_STR << std::endl;
return;
}
}
}
2018-10-14 15:56:54 +08:00
if (type == Simple)
{
std::string namespaceName;
2018-10-14 15:56:54 +08:00
for (auto iter = parameters.begin(); iter != parameters.end(); iter++)
{
2018-10-14 15:56:54 +08:00
if ((*iter)[0] == '-')
{
2018-10-14 15:56:54 +08:00
if (*iter == "-n" || *iter == "--namespace")
{
2018-10-14 15:56:54 +08:00
iter = parameters.erase(iter);
if (iter != parameters.end())
{
2018-10-14 15:56:54 +08:00
namespaceName = *iter;
iter = parameters.erase(iter);
break;
}
else
{
2018-10-14 15:56:54 +08:00
std::cout << "please enter namespace" << std::endl;
return;
}
2018-10-14 15:56:54 +08:00
}
else
{
2018-10-14 15:56:54 +08:00
std::cout << ARGS_ERROR_STR << std::endl;
return;
}
}
}
2018-10-14 15:56:54 +08:00
createSimpleController(parameters, namespaceName);
}
2018-10-14 15:56:54 +08:00
else if (type == WebSocket)
2018-08-22 14:27:45 +08:00
{
std::string namespaceName;
2018-10-14 15:56:54 +08:00
for (auto iter = parameters.begin(); iter != parameters.end(); iter++)
2018-08-22 14:27:45 +08:00
{
2018-10-14 15:56:54 +08:00
if ((*iter)[0] == '-')
2018-08-22 14:27:45 +08:00
{
2018-10-14 15:56:54 +08:00
if (*iter == "-n" || *iter == "--namespace")
2018-08-22 14:27:45 +08:00
{
2018-10-14 15:56:54 +08:00
iter = parameters.erase(iter);
if (iter != parameters.end())
2018-08-22 14:27:45 +08:00
{
2018-10-14 15:56:54 +08:00
namespaceName = *iter;
iter = parameters.erase(iter);
2018-08-22 14:27:45 +08:00
break;
}
else
{
2018-10-14 15:56:54 +08:00
std::cout << "please enter namespace" << std::endl;
2018-08-22 14:27:45 +08:00
return;
}
2018-10-14 15:56:54 +08:00
}
else
2018-08-22 14:27:45 +08:00
{
2018-10-14 15:56:54 +08:00
std::cout << ARGS_ERROR_STR << std::endl;
2018-08-22 14:27:45 +08:00
return;
}
}
}
2018-10-14 15:56:54 +08:00
createWebsockController(parameters, namespaceName);
2018-08-22 14:27:45 +08:00
}
else
createApiController(parameters);
}
2018-10-14 15:56:54 +08:00
void create_controller::createSimpleController(std::vector<std::string> &ctlNames, const std::string &namespaceName)
{
2018-10-14 15:56:54 +08:00
for (auto iter = ctlNames.begin(); iter != ctlNames.end(); iter++)
{
if ((*iter)[0] == '-')
{
2018-10-14 15:56:54 +08:00
std::cout << ARGS_ERROR_STR << std::endl;
return;
}
}
2018-10-14 15:56:54 +08:00
for (auto ctlName : ctlNames)
{
2018-10-14 15:56:54 +08:00
createSimpleController(ctlName, namespaceName);
}
}
2018-10-14 15:56:54 +08:00
void create_controller::createSimpleController(const std::string &ctlName, const std::string &namespaceName)
{
2018-10-14 15:56:54 +08:00
std::cout << "create simple controller:" << namespaceName << (namespaceName == "" ? "" : "::") << ctlName << std::endl;
std::string headFileName = ctlName + ".h";
std::string sourceFilename = ctlName + ".cc";
std::ofstream oHeadFile(headFileName.c_str(), std::ofstream::out);
std::ofstream oSourceFile(sourceFilename.c_str(), std::ofstream::out);
if (!oHeadFile || !oSourceFile)
return;
2018-10-14 15:56:54 +08:00
newSimpleControllerHeaderFile(oHeadFile, ctlName, namespaceName);
newSimpleControllerSourceFile(oSourceFile, ctlName, namespaceName);
}
2018-08-22 14:27:45 +08:00
2018-10-14 15:56:54 +08:00
void create_controller::createWebsockController(std::vector<std::string> &ctlNames, const std::string &namespaceName)
2018-08-22 14:27:45 +08:00
{
2018-10-14 15:56:54 +08:00
for (auto iter = ctlNames.begin(); iter != ctlNames.end(); iter++)
2018-08-22 14:27:45 +08:00
{
if ((*iter)[0] == '-')
{
2018-10-14 15:56:54 +08:00
std::cout << ARGS_ERROR_STR << std::endl;
2018-08-22 14:27:45 +08:00
return;
}
}
2018-10-14 15:56:54 +08:00
for (auto ctlName : ctlNames)
2018-08-22 14:27:45 +08:00
{
2018-10-14 15:56:54 +08:00
createWebsockController(ctlName, namespaceName);
2018-08-22 14:27:45 +08:00
}
}
2018-10-14 15:56:54 +08:00
void create_controller::createWebsockController(const std::string &ctlName, const std::string &namespaceName)
2018-08-22 14:27:45 +08:00
{
2018-10-14 15:56:54 +08:00
std::cout << "create websocket controller:" << namespaceName << (namespaceName == "" ? "" : "::") << ctlName << std::endl;
std::string headFileName = ctlName + ".h";
std::string sourceFilename = ctlName + ".cc";
std::ofstream oHeadFile(headFileName.c_str(), std::ofstream::out);
std::ofstream oSourceFile(sourceFilename.c_str(), std::ofstream::out);
if (!oHeadFile || !oSourceFile)
2018-08-22 14:27:45 +08:00
return;
2018-10-14 15:56:54 +08:00
newWebsockControllerHeaderFile(oHeadFile, ctlName, namespaceName);
newWebsockControllerSourceFile(oSourceFile, ctlName, namespaceName);
2018-08-22 14:27:45 +08:00
}
2018-10-14 15:56:54 +08:00
void create_controller::newSimpleControllerHeaderFile(std::ofstream &file, const std::string &ctlName, const std::string &namespaceName)
{
2018-10-14 15:56:54 +08:00
file << "#pragma once\n";
file << "#include <drogon/HttpSimpleController.h>\n";
file << "using namespace drogon;\n";
std::string indent = "";
auto namespace_name = namespaceName;
if (namespace_name != "")
{
auto pos = namespace_name.find("::");
while (pos != std::string::npos)
2018-08-22 14:27:45 +08:00
{
2018-10-14 15:56:54 +08:00
auto namespaceI = namespace_name.substr(0, pos);
namespace_name = namespace_name.substr(pos + 2);
file << indent << "namespace " << namespaceI << "\n";
file << indent << "{\n";
2018-08-22 14:27:45 +08:00
indent.append(" ");
2018-10-14 15:56:54 +08:00
pos = namespace_name.find("::");
2018-08-22 14:27:45 +08:00
}
2018-10-14 15:56:54 +08:00
if (!namespace_name.empty())
2018-08-22 14:27:45 +08:00
{
2018-10-14 15:56:54 +08:00
file << indent << "namespace " << namespace_name << "\n";
file << indent << "{\n";
2018-08-22 14:27:45 +08:00
indent.append(" ");
}
2018-05-29 13:57:10 +08:00
}
2018-10-14 15:56:54 +08:00
file << indent << "class " << ctlName << ":public drogon::HttpSimpleController<" << ctlName << ">\n";
file << indent << "{\n";
file << indent << "public:\n";
//TestController(){}
file << indent << " virtual void asyncHandleHttpRequest(const HttpRequestPtr& req,const std::function<void (const HttpResponsePtr &)> & callback)override;\n";
2018-10-14 15:56:54 +08:00
file << indent << " PATH_LIST_BEGIN\n";
file << indent << " //list path definitions here;\n";
2018-10-20 13:45:17 +08:00
file << indent << " //PATH_ADD(\"/path\",\"filter1\",\"filter2\",HttpMethod1,HttpMethod2...);\n";
2018-10-14 15:56:54 +08:00
file << indent << " PATH_LIST_END\n";
file << indent << "};\n";
if (indent == "")
2018-08-22 14:27:45 +08:00
return;
2018-10-14 15:56:54 +08:00
do
{
indent.resize(indent.length() - 4);
file << indent << "}\n";
} while (indent != "");
}
2018-10-14 15:56:54 +08:00
void create_controller::newSimpleControllerSourceFile(std::ofstream &file, const std::string &ctlName, const std::string &namespaceName)
{
2018-10-14 15:56:54 +08:00
file << "#include \"" << ctlName << ".h\"\n";
if (namespaceName != "")
file << "using namespace " << namespaceName << ";\n";
file << "void " << ctlName << "::asyncHandleHttpRequest(const HttpRequestPtr& req,const std::function<void (const HttpResponsePtr &)> & callback)\n";
file << "{\n";
file << " //write your application logic here\n";
file << "}";
}
2018-08-22 14:27:45 +08:00
2018-10-14 15:56:54 +08:00
void create_controller::newWebsockControllerHeaderFile(std::ofstream &file, const std::string &ctlName, const std::string &namespaceName)
2018-08-22 14:27:45 +08:00
{
2018-10-14 15:56:54 +08:00
file << "#pragma once\n";
file << "#include <drogon/WebSocketController.h>\n";
file << "using namespace drogon;\n";
std::string indent = "";
auto namespace_name = namespaceName;
if (namespace_name != "")
{
auto pos = namespace_name.find("::");
while (pos != std::string::npos)
2018-08-22 14:27:45 +08:00
{
2018-10-14 15:56:54 +08:00
auto namespaceI = namespace_name.substr(0, pos);
namespace_name = namespace_name.substr(pos + 2);
file << indent << "namespace " << namespaceI << "\n";
file << indent << "{\n";
2018-08-22 14:27:45 +08:00
indent.append(" ");
2018-10-14 15:56:54 +08:00
pos = namespace_name.find("::");
2018-08-22 14:27:45 +08:00
}
2018-10-14 15:56:54 +08:00
if (!namespace_name.empty())
2018-08-22 14:27:45 +08:00
{
2018-10-14 15:56:54 +08:00
file << indent << "namespace " << namespace_name << "\n";
file << indent << "{\n";
2018-08-22 14:27:45 +08:00
indent.append(" ");
}
}
2018-10-14 15:56:54 +08:00
file << indent << "class " << ctlName << ":public drogon::WebSocketController<" << ctlName << ">\n";
file << indent << "{\n";
file << indent << "public:\n";
2018-08-22 14:27:45 +08:00
//TestController(){}
2018-10-14 15:56:54 +08:00
// virtual void handleNewMessage(const WebSocketConnectionPtr&,
// trantor::MsgBuffer*)=0;
// //on new connection or after disconnect
// virtual void handleConnection(const WebSocketConnectionPtr&)=0;
file << indent << " virtual void handleNewMessage(const WebSocketConnectionPtr&,\n";
file << indent << " std::string &&)override;\n";
file << indent << " virtual void handleNewConnection(const HttpRequestPtr &,\n";
file << indent << " const WebSocketConnectionPtr&)override;\n";
file << indent << " virtual void handleConnectionClosed(const WebSocketConnectionPtr&)override;\n";
file << indent << " WS_PATH_LIST_BEGIN\n";
file << indent << " //list path definitions here;\n";
file << indent << " //WS_PATH_ADD(\"/path\",\"filter1\",\"filter2\",...);\n";
file << indent << " WS_PATH_LIST_END\n";
file << indent << "};\n";
if (indent == "")
2018-08-22 14:27:45 +08:00
return;
2018-10-14 15:56:54 +08:00
do
{
indent.resize(indent.length() - 4);
file << indent << "}\n";
} while (indent != "");
2018-08-22 14:27:45 +08:00
}
2018-10-14 15:56:54 +08:00
void create_controller::newWebsockControllerSourceFile(std::ofstream &file, const std::string &ctlName, const std::string &namespaceName)
2018-08-22 14:27:45 +08:00
{
2018-10-14 15:56:54 +08:00
file << "#include \"" << ctlName << ".h\"\n";
if (namespaceName != "")
file << "using namespace " << namespaceName << ";\n";
file << "void " << ctlName << "::handleNewMessage(const WebSocketConnectionPtr& wsConnPtr,std::string &&message)\n";
file << "{\n";
file << " //write your application logic here\n";
file << "}\n";
file << "void " << ctlName << "::handleNewConnection(const HttpRequestPtr &req,const WebSocketConnectionPtr& wsConnPtr)\n";
file << "{\n";
file << " //write your application logic here\n";
file << "}\n";
file << "void " << ctlName << "::handleConnectionClosed(const WebSocketConnectionPtr& wsConnPtr)\n";
file << "{\n";
file << " //write your application logic here\n";
file << "}\n";
2018-08-22 14:27:45 +08:00
}
void create_controller::createApiController(std::vector<std::string> &apiClasses)
{
2018-10-14 15:56:54 +08:00
for (auto iter = apiClasses.begin(); iter != apiClasses.end(); iter++)
{
if ((*iter)[0] == '-')
{
2018-10-14 15:56:54 +08:00
std::cout << ARGS_ERROR_STR << std::endl;
return;
}
}
2018-10-14 15:56:54 +08:00
for (auto className : apiClasses)
{
createApiController(className);
}
}
void create_controller::createApiController(const std::string &className)
{
std::regex regex("::");
2018-10-14 15:56:54 +08:00
std::string ctlName = std::regex_replace(className, regex, std::string("_"));
2018-10-14 15:56:54 +08:00
std::cout << "create api controller:" << className << std::endl;
std::string headFileName = ctlName + ".h";
std::string sourceFilename = ctlName + ".cc";
std::ofstream oHeadFile(headFileName.c_str(), std::ofstream::out);
std::ofstream oSourceFile(sourceFilename.c_str(), std::ofstream::out);
if (!oHeadFile || !oSourceFile)
return;
2018-10-14 15:56:54 +08:00
newApiControllerHeaderFile(oHeadFile, className);
newApiControllerSourceFile(oSourceFile, className, ctlName);
}
2018-10-14 15:56:54 +08:00
void create_controller::newApiControllerHeaderFile(std::ofstream &file, const std::string &className)
{
2018-10-14 15:56:54 +08:00
file << "#pragma once\n";
file << "#include <drogon/HttpApiController.h>\n";
file << "using namespace drogon;\n";
std::string indent = "";
std::string class_name = className;
std::string namepace_path = "/";
auto pos = class_name.find("::");
while (pos != std::string::npos)
{
2018-10-14 15:56:54 +08:00
auto namespaceName = class_name.substr(0, pos);
class_name = class_name.substr(pos + 2);
file << indent << "namespace " << namespaceName << "\n";
namepace_path.append(namespaceName).append("/");
2018-10-14 15:56:54 +08:00
file << indent << "{\n";
indent.append(" ");
2018-10-14 15:56:54 +08:00
pos = class_name.find("::");
}
2018-10-14 15:56:54 +08:00
file << indent << "class " << class_name << ":public drogon::HttpApiController<" << class_name << ">\n";
file << indent << "{\n";
file << indent << "public:\n";
indent.append(" ");
2018-10-14 15:56:54 +08:00
file << indent << "METHOD_LIST_BEGIN\n";
file << indent << "//use METHOD_ADD to add your custom processing function here;\n";
2018-10-20 13:45:17 +08:00
file << indent << "//METHOD_ADD(" << class_name << "::get,\"/get/{2}/{1}\",Get);"
2018-10-14 15:56:54 +08:00
"//path will be "
<< namepace_path << class_name << "/get/{arg2}/{arg1}\n";
file << indent << "//METHOD_ADD(" << class_name << "::your_method_name,\"/{1}/{2}/list\",\"drogon::GetFilter\");"
"//path will be "
<< namepace_path << class_name << "/{arg1}/{arg2}/list\n";
file << indent << "\n";
file << indent << "METHOD_LIST_END\n";
file << indent << "//your declaration of processing function maybe like this:\n";
file << indent << "//void get(const HttpRequestPtr& req,"
"const std::function<void (const HttpResponsePtr &)>&callback,int p1,std::string p2);\n";
file << indent << "//void your_method_name(const HttpRequestPtr& req,"
"const std::function<void (const HttpResponsePtr &)>&callback,double p1,int p2) const;\n";
indent.resize(indent.length() - 4);
file << indent << "};\n";
if (indent == "")
return;
2018-10-14 15:56:54 +08:00
do
{
indent.resize(indent.length() - 4);
file << indent << "}\n";
} while (indent != "");
}
2018-10-14 15:56:54 +08:00
void create_controller::newApiControllerSourceFile(std::ofstream &file, const std::string &className, const std::string &filename)
{
2018-10-14 15:56:54 +08:00
file << "#include \"" << filename << ".h\"\n";
auto pos = className.rfind("::");
auto class_name = className;
if (pos != std::string::npos)
{
2018-10-14 15:56:54 +08:00
auto namespacename = className.substr(0, pos);
file << "using namespace " << namespacename << ";\n";
class_name = className.substr(pos + 2);
}
2018-10-14 15:56:54 +08:00
file << "//add definition of your processing function here\n";
2018-06-23 19:22:20 +08:00
}