diff --git a/PageCompiler/doc/PageCompilerUserGuide.page b/PageCompiler/doc/PageCompilerUserGuide.page index 1403b06ed..61af51a0d 100644 --- a/PageCompiler/doc/PageCompilerUserGuide.page +++ b/PageCompiler/doc/PageCompilerUserGuide.page @@ -1,270 +1,318 @@ -POCO C++ Server Page Compiler User Guide -PageCompiler - -!!!Introduction -PageCompiler is a command line tool that translates HTML files (and other kinds of files), into -C++ code, more precisely, subclasses of Poco::Net::HTTPRequestHandler. -The source files can contain special directives that allow it to include C++ code into -the source file. The syntax of this directives is based on the syntax used for -Java Server Pages (JSP) and PHP. - -The following introductory sample shows the code for a simple page that displays the -current date and time. - - <%@ page class="TimeHandler" %> - <%! - #include "Poco/DateTime.h" - #include "Poco/DateTimeFormatter.h" - #include "Poco/DateTimeFormat.h" - - - using Poco::DateTime; - using Poco::DateTimeFormatter; - using Poco::DateTimeFormat; - %> - - <% - DateTime now; - std::string dt(DateTimeFormatter::format(now, DateTimeFormat::SORTABLE_FORMAT)); - %> - - - Time Sample - - -

Time Sample

-

<%= dt %>

- - ----- - -Sending the above code to the page compiler will generate two files, a header file -(<[TimeHandler.h]>) and an implementation file (<[TimeHandler.cpp]>). -The files define a subclass of Poco::Net::HTTPRequestHandler named <[TimeHandler]>. -The generated <[handleRequest]> member function contains code to send the HTML -code contained in the source file to the client, as well as the C++ code fragments found -in between the Scriptlet tags. - - -!!!C++ Server Page Syntax - -The following special tags are supported in a C++ server page (CPSP) file. - -!!Hidden Comment - -A hidden comment documents the CPSP file, but is not sent to the client. - - <%-- --%> ----- - -!!Implementation Declaration - -An implementation declaration is copied to the implementation file immediately after -the block containing the standard <[#include]> directives. -It is used to include additional header files and <[using]> declarations, -as well as to define classes needed later on. - - <%! - - ... - %> ----- - -!!Header Declaration - -A header declaration is copied to the header file immediately after the -block containing the standard <[#include]> directives. -It is usually used to include the header file containing the definition -of the base class for the request handler, if a custom base class -is required. - - <%!! - - ... - %> ----- - -!!Expression - -The result of any valid C++ expression can be directly inserted into the page, -provided the result can be written to an output stream. Note that the expression -must not end with a semicolon. - - <%= %> ----- - -!!Scriptlet - -Arbitrary C++ code fragments can be included using the Scriptlet directive. - - <% - - ... - %> ----- - -!!Include Directive - -Another CPSP file can be included into the current file using the Include -Directive. - - <%@ include page="" %> ----- - -If the given path is relative, it is considered relative to the path of -the currently processed CPSP file. - -!!Page Directive - -The Page Directive allows the definition of attributes that control -various aspects of C++ code generation. - - <%@ page ="" ... %> ----- - -The following page attributes are supported: - -!class - -Specifies the name of the generated class. -Defaults to the base name of the source file with the word "Handler" appended. - -!namespace - -If specified, sets the namespace where the generated classes will be in. -No namespace will be used if omitted. - -!baseClass - -Specifies the name of the class used as the base class for the generated -request handler class. -Defaults to Poco::Net::HTTPRequestHandler. Do not forget to add a Header Declaration -containing an <[#include]> directive for the header file containing the definition -of that class, otherwise the generated code won't compile. - -!ctorArg - -Allows to specify the type of a single argument being passed to the constructor -of the generated request handler class. Can only be used together with <[baseClass]>. -The argument is passed on to the constructor of the base class, therefore, one of the -constructors of the base class must also accept a single argument of the specified type. - -!export - -Allows to specify a DLL import/export directive that is being added to the request -handler class definition. Useful for exporting a request handler class from a -Windows DLL. - -!form - -Enable or disable automatic form handling. If enabled, which is the default, -a Poco::Net::HTMLForm object is automatically created in the request handler -and accessible through a variable named <[form]>. -Set the value to <[false]> to disable form handling. - -!formPartHandler - -Allows you to pass a Poco::Net::PartHandler object to the form object for -processing file uploads. A subclass of Poco::Net::PartHandler must be -defined (using an Implementation Declaration), and the constructor of the part -handler must take a (const) reference to the request handler instance as argument. - -!contentType - -Allows you to specify the MIME content type for the page. Defaults to text/html. - -!chunked - -Allows you to specify whether the response is sent using chunked transfer encoding. -Defaults to <[true]>. -Set the value to <[false]> to disable chunked transfer encoding. - -!session (OSP only) - -For use with the POCO Open Service Platform only. - -Specifies the identifier of the session obtained from the OSP Web Session Manager. -If specified, a Poco::OSP::Web::WebSession object will be available in the -request handler through a variable named <[session]>. The variable is of type -Poco::OSP::Web::WebSession::Ptr. - -!sessionTimeout (OSP only) - -For use with the POCO Open Service Platform only. - -Specifies the session timeout in minutes. - - -!!Implicit Objects - -The following objects are available in the handler code. - -!request - -The HTTP request object - an instance of Poco::Net::HTTPServerRequest. - -!response - -The HTTP response object - an instance of Poco::Net::HTTPServerRequest. - -!form - -An instance of Poco::Net::HTMLForm for processing form arguments. -Only available if form processing has not been disabled by -setting the <[form]> page attribute to <[false]>. - -!session (OSP only) - -An instance of Poco::OSP::Web::WebSession::Ptr for accessing the -Poco::OSP::Web::WebSession object for the current session. -Only available with the POCO Open Service Platform, and if the -<[session]> page attribute has been specified. - - -!!!Invoking the Page Compiler - -The Page Compiler is invoked from the command line. The file names of the -CPSP files to be compiled are specified as arguments. - -A number of options control the code generation. Options are specified -using the usual command-line option syntax for the current operating -system (e.g., <[/help]> on Windows, <[--help]> or <[-h]> on Unix). - - * help (h): display usage information - * define (D): define a configuration property - * config-file (f): load configuration properties from a file - * osp (O): add factory class definition/implementation for use with OSP - * apache (A): add factory class definition/implementation and shared library manifest for use with ApacheConnector - -!!Configuration Properties - -The Page Compiler supports one configuration property, named -<[PageCompiler.fileHeader]>, to optionally specify a header that is -included in every generated file. - -The file header can contain references to other configuration properties, -using the usual property syntax: <[${property}]>. - -For example, invoking the Page Compiler with the following configuration -file: - - PageCompiler.fileHeader = //\n// ${outputFileName}\n//\n ----- - -places the following header at the beginning of each generated file -(<[]> is replaced with the actual name of the file): - - // - // - // ----- - -The following pre-defined properties can be used in the file header: - - * <[${inputFileName}]>: the name of the input file (with directories removed) - * <[${inputFilePath}]>: the complete path of the input file - * <[${dateTime}]>: the current date and time (YYYY-MM-DD HH:MM:SS) - * <[${outputFileName}]>: the name of the current output file (header or implementation file), with - directories removed - * <[${outputFilePath}]>: the complete path of the current output file - +POCO C++ Server Page Compiler User Guide +PageCompiler + +!!!Introduction +PageCompiler is a command line tool that translates HTML files (and other kinds of files, such as +cascading style sheet files), into +C++ code, more precisely, subclasses of Poco::Net::HTTPRequestHandler. +The source files can contain special directives that allow it to include C++ code into +the source file. The syntax of this directives is based on the syntax used for +Java Server Pages (JSP) and PHP. + +The following introductory sample shows the code for a simple page that displays the +current date and time. + + <%@ page class="TimeHandler" %> + <%! + #include "Poco/DateTime.h" + #include "Poco/DateTimeFormatter.h" + #include "Poco/DateTimeFormat.h" + + + using Poco::DateTime; + using Poco::DateTimeFormatter; + using Poco::DateTimeFormat; + %> + + <% + DateTime now; + std::string dt(DateTimeFormatter::format(now, DateTimeFormat::SORTABLE_FORMAT)); + %> + + + Time Sample + + +

Time Sample

+

<%= dt %>

+ + +---- + +Sending the above code to the page compiler will generate two files, a header file +(<[TimeHandler.h]>) and an implementation file (<[TimeHandler.cpp]>). +The files define a subclass of Poco::Net::HTTPRequestHandler named <[TimeHandler]>. +The generated <[handleRequest]> member function contains code to send the HTML +code contained in the source file to the client, as well as the C++ code fragments found +in between the Scriptlet tags. + + +!!!C++ Server Page Syntax + +The following special tags are supported in a C++ server page (CPSP) file. + +!!Hidden Comment + +A hidden comment documents the CPSP file, but is not sent to the client. + + <%-- --%> +---- + +!!Implementation Declaration + +An implementation declaration is copied to the implementation file immediately after +the block containing the standard <[#include]> directives. +It is used to include additional header files and <[using]> declarations, +as well as to define classes needed later on. + + <%! + + ... + %> +---- + +!!Header Declaration + +A header declaration is copied to the header file immediately after the +block containing the standard <[#include]> directives. +It is usually used to include the header file containing the definition +of the base class for the request handler, if a custom base class +is required. + + <%!! + + ... + %> +---- + +!!Expression + +The result of any valid C++ expression can be directly inserted into the page, +provided the result can be written to an output stream. Note that the expression +must not end with a semicolon. + + <%= %> +---- + +!!Scriptlet + +Arbitrary C++ code fragments can be included using the Scriptlet directive. + + <% + + ... + %> +---- + +!!Include Directive + +Another CPSP file can be included into the current file using the Include +Directive. + + <%@ include page="" %> +---- + +If the given path is relative, it is considered relative to the path of +the currently processed CPSP file. + +!!Page Directive + +The Page Directive allows the definition of attributes that control +various aspects of C++ code generation. + + <%@ page ="" ... %> +---- + +The following page attributes are supported: + +!class + +Specifies the name of the generated class. +Defaults to the base name of the source file with the word "Handler" appended. + +!namespace + +If specified, sets the namespace where the generated classes will be in. +No namespace will be used if omitted. + +!baseClass + +Specifies the name of the class used as the base class for the generated +request handler class. +Defaults to Poco::Net::HTTPRequestHandler. Do not forget to add a Header Declaration +containing an <[#include]> directive for the header file containing the definition +of that class, otherwise the generated code won't compile. + +!ctorArg + +Allows to specify the type of a single argument being passed to the constructor +of the generated request handler class. Can only be used together with <[baseClass]>. +The argument is passed on to the constructor of the base class, therefore, one of the +constructors of the base class must also accept a single argument of the specified type. + +!export + +Allows to specify a DLL import/export directive that is being added to the request +handler class definition. Useful for exporting a request handler class from a +Windows DLL. + +!form + +Enable or disable automatic form handling. If enabled, which is the default, +a Poco::Net::HTMLForm object is automatically created in the request handler +and accessible through a variable named <[form]>. +Set the value to <[false]> to disable form handling. + +!formPartHandler + +Allows you to pass a Poco::Net::PartHandler object to the form object for +processing file uploads. A subclass of Poco::Net::PartHandler must be +defined (using an Implementation Declaration), and the constructor of the part +handler must take a (const) reference to the request handler instance as argument. + +!contentType + +Allows you to specify the MIME content type for the page. Defaults to text/html. + +!chunked + +Allows you to specify whether the response is sent using chunked transfer encoding. +Defaults to <[true]>. +Set the value to <[false]> to disable chunked transfer encoding. + +!precondition + +Allows the specification of a precondition, which must be a C++ expression +valid in the context of the request handler. This can be used to implement +authentication. + +Example: + + <%@ page + class="AuthSamplePage" + precondition="checkCredentials(request, response)" + %> + + <%! + bool checkCredentials(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) + { + bool isAuthenticated = false; + if (request.hasCredentials()) + { + std::string scheme; + std::string authInfo; + request.getCredentials(scheme, authInfo); + if (scheme == Poco::Net::HTTPBasicCredentials::SCHEME) + { + Poco::Net::HTTPBasicCredentials cred(request); + isAuthenticated = (cred.getUsername() == "joeuser" && cred.getPassword() == "s3cr3t"); + } + } + if (!isAuthenticated) + { + response.requireAuthentication("Restricted Area"); + response.send(); + } + return isAuthenticated; + } + %> + + + Restricted Area + + +

Restricted Area

+ + +---- + + +!session (OSP only) + +For use with the POCO Open Service Platform only. + +Specifies the identifier of the session obtained from the OSP Web Session Manager. +If specified, a Poco::OSP::Web::WebSession object will be available in the +request handler through a variable named <[session]>. The variable is of type +Poco::OSP::Web::WebSession::Ptr. + +!sessionTimeout (OSP only) + +For use with the POCO Open Service Platform only. + +Specifies the session timeout in minutes. + + +!!Implicit Objects + +The following objects are available in the handler code. + +!request + +The HTTP request object - an instance of Poco::Net::HTTPServerRequest. + +!response + +The HTTP response object - an instance of Poco::Net::HTTPServerRequest. + +!form + +An instance of Poco::Net::HTMLForm for processing form arguments. +Only available if form processing has not been disabled by +setting the <[form]> page attribute to <[false]>. + +!session (OSP only) + +An instance of Poco::OSP::Web::WebSession::Ptr for accessing the +Poco::OSP::Web::WebSession object for the current session. +Only available with the POCO Open Service Platform, and if the +<[session]> page attribute has been specified. + + +!!!Invoking the Page Compiler + +The Page Compiler is invoked from the command line. The file names of the +CPSP files to be compiled are specified as arguments. + +A number of options control the code generation. Options are specified +using the usual command-line option syntax for the current operating +system (e.g., <[/help]> on Windows, <[--help]> or <[-h]> on Unix). + + * help (h): display usage information + * define (D): define a configuration property + * config-file (f): load configuration properties from a file + * osp (O): add factory class definition/implementation for use with OSP + * apache (A): add factory class definition/implementation and shared library manifest for use with ApacheConnector + +!!Configuration Properties + +The Page Compiler supports one configuration property, named +<[PageCompiler.fileHeader]>, to optionally specify a header that is +included in every generated file. + +The file header can contain references to other configuration properties, +using the usual property syntax: <[${property}]>. + +For example, invoking the Page Compiler with the following configuration +file: + + PageCompiler.fileHeader = //\n// ${outputFileName}\n//\n +---- + +places the following header at the beginning of each generated file +(<[]> is replaced with the actual name of the file): + + // + // + // +---- + +The following pre-defined properties can be used in the file header: + + * <[${inputFileName}]>: the name of the input file (with directories removed) + * <[${inputFilePath}]>: the complete path of the input file + * <[${dateTime}]>: the current date and time (YYYY-MM-DD HH:MM:SS) + * <[${outputFileName}]>: the name of the current output file (header or implementation file), with + directories removed + * <[${outputFilePath}]>: the complete path of the current output file + diff --git a/PageCompiler/src/CodeWriter.cpp b/PageCompiler/src/CodeWriter.cpp index f8393b842..63d5ce14b 100644 --- a/PageCompiler/src/CodeWriter.cpp +++ b/PageCompiler/src/CodeWriter.cpp @@ -1,292 +1,297 @@ -// -// CodeWriter.cpp -// -// $Id: //poco/Main/PageCompiler/src/CodeWriter.cpp#1 $ -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#include "CodeWriter.h" -#include "Page.h" -#include "Poco/Path.h" -#include "Poco/StringTokenizer.h" - - -using Poco::Path; -using Poco::StringTokenizer; - - -CodeWriter::CodeWriter(const Page& page, const std::string& clazz): - _page(page), - _class(clazz) -{ -} - - -CodeWriter::~CodeWriter() -{ -} - - -void CodeWriter::writeHeader(std::ostream& ostr, const std::string& headerFileName) -{ - beginGuard(ostr, headerFileName); - writeHeaderIncludes(ostr); - ostr << "\n\n"; - - std::string decls(_page.headerDecls().str()); - if (!decls.empty()) - { - ostr << decls << "\n\n"; - } - - beginNamespace(ostr); - writeHandlerClass(ostr); - writeFactoryClass(ostr); - endNamespace(ostr); - endGuard(ostr, headerFileName); -} - - -void CodeWriter::writeImpl(std::ostream& ostr, const std::string& headerFileName) -{ - ostr << "#include \"" << headerFileName << "\"\n"; - writeImplIncludes(ostr); - ostr << "\n\n"; - - std::string decls(_page.implDecls().str()); - if (!decls.empty()) - { - ostr << decls << "\n\n"; - } - - beginNamespace(ostr); - writeConstructor(ostr); - writeHandler(ostr); - writeFactory(ostr); - endNamespace(ostr); - writeManifest(ostr); -} - - -void CodeWriter::beginNamespace(std::ostream& ostr) -{ - std::string ns = _page.get("page.namespace", ""); - if (!ns.empty()) - { - StringTokenizer tok(ns, ":", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM); - for (StringTokenizer::Iterator it = tok.begin(); it != tok.end(); ++it) - { - ostr << "namespace " << *it << " {\n"; - } - ostr << "\n\n"; - } -} - -void CodeWriter::endNamespace(std::ostream& ostr) -{ - std::string ns = _page.get("page.namespace", ""); - if (!ns.empty()) - { - ostr << "\n\n"; - StringTokenizer tok(ns, ":", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM); - for (StringTokenizer::Iterator it = tok.begin(); it != tok.end(); ++it) - { - ostr << "} "; - } - ostr << "// namespace " << ns << "\n"; - } -} - - -void CodeWriter::beginGuard(std::ostream& ostr, const std::string& headerFileName) -{ - Path p(headerFileName); - std::string guard(p.getBaseName()); - guard += "_INCLUDED"; - ostr << "#ifndef " << guard << "\n"; - ostr << "#define " << guard << "\n"; - ostr << "\n\n"; -} - - -void CodeWriter::endGuard(std::ostream& ostr, const std::string& headerFileName) -{ - Path p(headerFileName); - std::string guard(p.getBaseName()); - guard += "_INCLUDED"; - ostr << "\n\n"; - ostr << "#endif // " << guard << "\n"; -} - - -void CodeWriter::handlerClass(std::ostream& ostr, const std::string& base, const std::string& ctorArg) -{ - std::string exprt(_page.get("page.export", "")); - if (!exprt.empty()) exprt += ' '; - - ostr << "class " << exprt << _class << ": public " << base << "\n"; - ostr << "{\n"; - ostr << "public:\n"; - if (!ctorArg.empty()) - { - ostr << "\t" << _class << "(" << ctorArg << ");\n"; - ostr << "\n"; - } - ostr << "\tvoid handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response);\n"; - writeHandlerMembers(ostr); - ostr << "};\n"; -} - - -void CodeWriter::factoryClass(std::ostream& ostr, const std::string& base) -{ - ostr << "class " << _class << "Factory: public " << base << "\n"; - ostr << "{\n"; - ostr << "public:\n"; - ostr << "\tPoco::Net::HTTPRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request);\n"; - ostr << "};\n"; -} - - -void CodeWriter::factoryImpl(std::ostream& ostr, const std::string& arg) -{ - ostr << "Poco::Net::HTTPRequestHandler* " << _class << "Factory::createRequestHandler(const Poco::Net::HTTPServerRequest& request)\n"; - ostr << "{\n"; - ostr << "\treturn new " << _class << "(" << arg << ");\n"; - ostr << "}\n"; -} - - -void CodeWriter::writeHeaderIncludes(std::ostream& ostr) -{ - ostr << "#include \"Poco/Net/HTTPRequestHandler.h\"\n"; -} - - -void CodeWriter::writeHandlerClass(std::ostream& ostr) -{ - std::string base(_page.get("page.baseClass", "Poco::Net::HTTPRequestHandler")); - std::string ctorArg; - ctorArg = _page.get("page.ctorArg", ""); - - handlerClass(ostr, base, ctorArg); -} - - -void CodeWriter::writeHandlerMembers(std::ostream& ostr) -{ -} - - -void CodeWriter::writeFactoryClass(std::ostream& ostr) -{ -} - - -void CodeWriter::writeImplIncludes(std::ostream& ostr) -{ - ostr << "#include \"Poco/Net/HTTPServerRequest.h\"\n"; - ostr << "#include \"Poco/Net/HTTPServerResponse.h\"\n"; - ostr << "#include \"Poco/Net/HTMLForm.h\"\n"; -} - - -void CodeWriter::writeConstructor(std::ostream& ostr) -{ - std::string base(_page.get("page.baseClass", "Poco::Net::HTTPRequestHandler")); - std::string ctorArg(_page.get("page.ctorArg", "")); - if (!ctorArg.empty()) - { - ostr << _class << "::" << _class << "(" << ctorArg << " arg):\n"; - ostr << "\t" << base << "(arg)\n"; - ostr << "{\n}\n"; - ostr << "\n\n"; - } -} - - -void CodeWriter::writeHandler(std::ostream& ostr) -{ - ostr << "void " << _class << "::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response)\n"; - ostr << "{\n"; - writeSession(ostr); - writeForm(ostr); - writeRequest(ostr); - ostr << _page.handler().str(); - ostr << "}\n"; -} - - -void CodeWriter::writeFactory(std::ostream& ostr) -{ -} - - -void CodeWriter::writeManifest(std::ostream& ostr) -{ -} - - -void CodeWriter::writeSession(std::ostream& ostr) -{ -} - - -void CodeWriter::writeForm(std::ostream& ostr) -{ - if (_page.get("page.form", "true") != "false") - { - std::string partHandler(_page.get("page.formPartHandler", "")); - if (!partHandler.empty()) - { - ostr << "\t" << partHandler << " cpspPartHandler(*this);\n"; - } - ostr << "\tPoco::Net::HTMLForm form(request, request.stream()"; - if (!partHandler.empty()) - { - ostr << ", cpspPartHandler"; - } - ostr << ");\n"; - } -} - - -void CodeWriter::writeRequest(std::ostream& ostr) -{ - std::string contentType(_page.get("page.contentType", "text/html")); - std::string chunked(_page.get("page.chunked", "true")); - - if (chunked != "false") - { - ostr << "\tresponse.setChunkedTransferEncoding(true);\n"; - } - - ostr << "\tresponse.setContentType(\"" << contentType << "\");\n"; - ostr << "\n"; - ostr << "\tstd::ostream& ostr = response.send();\n"; -} \ No newline at end of file +// +// CodeWriter.cpp +// +// $Id: //poco/1.3/PageCompiler/src/CodeWriter.cpp#1 $ +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "CodeWriter.h" +#include "Page.h" +#include "Poco/Path.h" +#include "Poco/StringTokenizer.h" + + +using Poco::Path; +using Poco::StringTokenizer; + + +CodeWriter::CodeWriter(const Page& page, const std::string& clazz): + _page(page), + _class(clazz) +{ +} + + +CodeWriter::~CodeWriter() +{ +} + + +void CodeWriter::writeHeader(std::ostream& ostr, const std::string& headerFileName) +{ + beginGuard(ostr, headerFileName); + writeHeaderIncludes(ostr); + ostr << "\n\n"; + + std::string decls(_page.headerDecls().str()); + if (!decls.empty()) + { + ostr << decls << "\n\n"; + } + + beginNamespace(ostr); + writeHandlerClass(ostr); + writeFactoryClass(ostr); + endNamespace(ostr); + endGuard(ostr, headerFileName); +} + + +void CodeWriter::writeImpl(std::ostream& ostr, const std::string& headerFileName) +{ + ostr << "#include \"" << headerFileName << "\"\n"; + writeImplIncludes(ostr); + ostr << "\n\n"; + + std::string decls(_page.implDecls().str()); + if (!decls.empty()) + { + ostr << decls << "\n\n"; + } + + beginNamespace(ostr); + writeConstructor(ostr); + writeHandler(ostr); + writeFactory(ostr); + endNamespace(ostr); + writeManifest(ostr); +} + + +void CodeWriter::beginNamespace(std::ostream& ostr) +{ + std::string ns = _page.get("page.namespace", ""); + if (!ns.empty()) + { + StringTokenizer tok(ns, ":", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM); + for (StringTokenizer::Iterator it = tok.begin(); it != tok.end(); ++it) + { + ostr << "namespace " << *it << " {\n"; + } + ostr << "\n\n"; + } +} + +void CodeWriter::endNamespace(std::ostream& ostr) +{ + std::string ns = _page.get("page.namespace", ""); + if (!ns.empty()) + { + ostr << "\n\n"; + StringTokenizer tok(ns, ":", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM); + for (StringTokenizer::Iterator it = tok.begin(); it != tok.end(); ++it) + { + ostr << "} "; + } + ostr << "// namespace " << ns << "\n"; + } +} + + +void CodeWriter::beginGuard(std::ostream& ostr, const std::string& headerFileName) +{ + Path p(headerFileName); + std::string guard(p.getBaseName()); + guard += "_INCLUDED"; + ostr << "#ifndef " << guard << "\n"; + ostr << "#define " << guard << "\n"; + ostr << "\n\n"; +} + + +void CodeWriter::endGuard(std::ostream& ostr, const std::string& headerFileName) +{ + Path p(headerFileName); + std::string guard(p.getBaseName()); + guard += "_INCLUDED"; + ostr << "\n\n"; + ostr << "#endif // " << guard << "\n"; +} + + +void CodeWriter::handlerClass(std::ostream& ostr, const std::string& base, const std::string& ctorArg) +{ + std::string exprt(_page.get("page.export", "")); + if (!exprt.empty()) exprt += ' '; + + ostr << "class " << exprt << _class << ": public " << base << "\n"; + ostr << "{\n"; + ostr << "public:\n"; + if (!ctorArg.empty()) + { + ostr << "\t" << _class << "(" << ctorArg << ");\n"; + ostr << "\n"; + } + ostr << "\tvoid handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response);\n"; + writeHandlerMembers(ostr); + ostr << "};\n"; +} + + +void CodeWriter::factoryClass(std::ostream& ostr, const std::string& base) +{ + ostr << "class " << _class << "Factory: public " << base << "\n"; + ostr << "{\n"; + ostr << "public:\n"; + ostr << "\tPoco::Net::HTTPRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request);\n"; + ostr << "};\n"; +} + + +void CodeWriter::factoryImpl(std::ostream& ostr, const std::string& arg) +{ + ostr << "Poco::Net::HTTPRequestHandler* " << _class << "Factory::createRequestHandler(const Poco::Net::HTTPServerRequest& request)\n"; + ostr << "{\n"; + ostr << "\treturn new " << _class << "(" << arg << ");\n"; + ostr << "}\n"; +} + + +void CodeWriter::writeHeaderIncludes(std::ostream& ostr) +{ + ostr << "#include \"Poco/Net/HTTPRequestHandler.h\"\n"; +} + + +void CodeWriter::writeHandlerClass(std::ostream& ostr) +{ + std::string base(_page.get("page.baseClass", "Poco::Net::HTTPRequestHandler")); + std::string ctorArg; + ctorArg = _page.get("page.ctorArg", ""); + + handlerClass(ostr, base, ctorArg); +} + + +void CodeWriter::writeHandlerMembers(std::ostream& ostr) +{ +} + + +void CodeWriter::writeFactoryClass(std::ostream& ostr) +{ +} + + +void CodeWriter::writeImplIncludes(std::ostream& ostr) +{ + ostr << "#include \"Poco/Net/HTTPServerRequest.h\"\n"; + ostr << "#include \"Poco/Net/HTTPServerResponse.h\"\n"; + ostr << "#include \"Poco/Net/HTMLForm.h\"\n"; +} + + +void CodeWriter::writeConstructor(std::ostream& ostr) +{ + std::string base(_page.get("page.baseClass", "Poco::Net::HTTPRequestHandler")); + std::string ctorArg(_page.get("page.ctorArg", "")); + if (!ctorArg.empty()) + { + ostr << _class << "::" << _class << "(" << ctorArg << " arg):\n"; + ostr << "\t" << base << "(arg)\n"; + ostr << "{\n}\n"; + ostr << "\n\n"; + } +} + + +void CodeWriter::writeHandler(std::ostream& ostr) +{ + ostr << "void " << _class << "::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response)\n"; + ostr << "{\n"; + if (_page.has("page.precondition")) + { + ostr << "\tif (!(" << _page.get("page.precondition") << ")) return;\n\n"; + } + writeSession(ostr); + writeForm(ostr); + writeRequest(ostr); + ostr << _page.handler().str(); + ostr << "}\n"; +} + + +void CodeWriter::writeFactory(std::ostream& ostr) +{ +} + + +void CodeWriter::writeManifest(std::ostream& ostr) +{ +} + + +void CodeWriter::writeSession(std::ostream& ostr) +{ +} + + +void CodeWriter::writeForm(std::ostream& ostr) +{ + if (_page.get("page.form", "true") != "false") + { + std::string partHandler(_page.get("page.formPartHandler", "")); + if (!partHandler.empty()) + { + ostr << "\t" << partHandler << " cpspPartHandler(*this);\n"; + } + ostr << "\tPoco::Net::HTMLForm form(request, request.stream()"; + if (!partHandler.empty()) + { + ostr << ", cpspPartHandler"; + } + ostr << ");\n"; + } +} + + +void CodeWriter::writeRequest(std::ostream& ostr) +{ + std::string contentType(_page.get("page.contentType", "text/html")); + std::string chunked(_page.get("page.chunked", "true")); + + if (chunked != "false") + { + ostr << "\tresponse.setChunkedTransferEncoding(true);\n"; + } + + ostr << "\tresponse.setContentType(\"" << contentType << "\");\n"; + ostr << "\n"; + ostr << "\tstd::ostream& ostr = response.send();\n"; + ostr << "\tif (request.getMethod() == Poco::Net::HTTPRequest::HTTP_HEAD) return;\n"; +} diff --git a/PageCompiler/src/CodeWriter.h b/PageCompiler/src/CodeWriter.h index e7da4a9f7..6e7107c71 100644 --- a/PageCompiler/src/CodeWriter.h +++ b/PageCompiler/src/CodeWriter.h @@ -1,115 +1,115 @@ -// -// CodeWriter.h -// -// $Id: //poco/Main/PageCompiler/src/CodeWriter.h#1 $ -// -// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. -// and Contributors. -// -// Permission is hereby granted, free of charge, to any person or organization -// obtaining a copy of the software and accompanying documentation covered by -// this license (the "Software") to use, reproduce, display, distribute, -// execute, and transmit the Software, and to prepare derivative works of the -// Software, and to permit third-parties to whom the Software is furnished to -// do so, all subject to the following: -// -// The copyright notices in the Software and this entire statement, including -// the above license grant, this restriction and the following disclaimer, -// must be included in all copies of the Software, in whole or in part, and -// all derivative works of the Software, unless such copies or derivative -// works are solely in the form of machine-executable object code generated by -// a source language processor. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// - - -#ifndef CodeWriter_INCLUDED -#define CodeWriter_INCLUDED - - -#include "Poco/Poco.h" -#include - - -class Page; - - -class CodeWriter - /// This class implements the code generator for - /// generating C++ header and implementation files - /// from C++ Server Pages. -{ -public: - CodeWriter(const Page& page, const std::string& clazz); - /// Creates the CodeWriter, using the given Page. - - ~CodeWriter(); - /// Destroys the PageReader. - - virtual void writeHeader(std::ostream& ostr, const std::string& headerFileName); - /// Writes the header file contents to the given stream. - - virtual void writeImpl(std::ostream& ostr, const std::string& headerFileName); - /// Writes the implementation file contents to the given stream. - - const Page& page() const; - /// Returns a const reference to the Page. - - const std::string& clazz() const; - /// Returns the name of the handler class. - -protected: - virtual void writeHeaderIncludes(std::ostream& ostr); - virtual void writeHandlerClass(std::ostream& ostr); - virtual void writeHandlerMembers(std::ostream& ostr); - virtual void writeFactoryClass(std::ostream& ostr); - virtual void writeImplIncludes(std::ostream& ostr); - virtual void writeConstructor(std::ostream& ostr); - virtual void writeHandler(std::ostream& ostr); - virtual void writeFactory(std::ostream& ostr); - virtual void writeSession(std::ostream& ostr); - virtual void writeForm(std::ostream& ostr); - virtual void writeRequest(std::ostream& ostr); - virtual void writeManifest(std::ostream& ostr); - - void beginGuard(std::ostream& ostr, const std::string& headerFileName); - void endGuard(std::ostream& ostr, const std::string& headerFileName); - void beginNamespace(std::ostream& ostr); - void endNamespace(std::ostream& ostr); - void handlerClass(std::ostream& ostr, const std::string& base, const std::string& ctorArg); - void factoryClass(std::ostream& ostr, const std::string& base); - void factoryImpl(std::ostream& ostr, const std::string& arg); - -private: - CodeWriter(); - CodeWriter(const CodeWriter&); - CodeWriter& operator = (const CodeWriter&); - - const Page& _page; - std::string _class; -}; - - -// -// inlines -// -inline const Page& CodeWriter::page() const -{ - return _page; -} - - -inline const std::string& CodeWriter::clazz() const -{ - return _class; -} - - -#endif // CodeWriter_INCLUDED +// +// CodeWriter.h +// +// $Id: //poco/1.3/PageCompiler/src/CodeWriter.h#1 $ +// +// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef CodeWriter_INCLUDED +#define CodeWriter_INCLUDED + + +#include "Poco/Poco.h" +#include + + +class Page; + + +class CodeWriter + /// This class implements the code generator for + /// generating C++ header and implementation files + /// from C++ Server Pages. +{ +public: + CodeWriter(const Page& page, const std::string& clazz); + /// Creates the CodeWriter, using the given Page. + + virtual ~CodeWriter(); + /// Destroys the PageReader. + + virtual void writeHeader(std::ostream& ostr, const std::string& headerFileName); + /// Writes the header file contents to the given stream. + + virtual void writeImpl(std::ostream& ostr, const std::string& headerFileName); + /// Writes the implementation file contents to the given stream. + + const Page& page() const; + /// Returns a const reference to the Page. + + const std::string& clazz() const; + /// Returns the name of the handler class. + +protected: + virtual void writeHeaderIncludes(std::ostream& ostr); + virtual void writeHandlerClass(std::ostream& ostr); + virtual void writeHandlerMembers(std::ostream& ostr); + virtual void writeFactoryClass(std::ostream& ostr); + virtual void writeImplIncludes(std::ostream& ostr); + virtual void writeConstructor(std::ostream& ostr); + virtual void writeHandler(std::ostream& ostr); + virtual void writeFactory(std::ostream& ostr); + virtual void writeSession(std::ostream& ostr); + virtual void writeForm(std::ostream& ostr); + virtual void writeRequest(std::ostream& ostr); + virtual void writeManifest(std::ostream& ostr); + + void beginGuard(std::ostream& ostr, const std::string& headerFileName); + void endGuard(std::ostream& ostr, const std::string& headerFileName); + void beginNamespace(std::ostream& ostr); + void endNamespace(std::ostream& ostr); + void handlerClass(std::ostream& ostr, const std::string& base, const std::string& ctorArg); + void factoryClass(std::ostream& ostr, const std::string& base); + void factoryImpl(std::ostream& ostr, const std::string& arg); + +private: + CodeWriter(); + CodeWriter(const CodeWriter&); + CodeWriter& operator = (const CodeWriter&); + + const Page& _page; + std::string _class; +}; + + +// +// inlines +// +inline const Page& CodeWriter::page() const +{ + return _page; +} + + +inline const std::string& CodeWriter::clazz() const +{ + return _class; +} + + +#endif // CodeWriter_INCLUDED