improvements to PageCompiler (new precondition page attribute)

This commit is contained in:
Guenter Obiltschnig 2008-06-10 15:21:44 +00:00
parent 9f751f5e9a
commit ecefa6121c
3 changed files with 730 additions and 677 deletions

View File

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

View File

@ -1,292 +1,297 @@
// //
// CodeWriter.cpp // CodeWriter.cpp
// //
// $Id: //poco/Main/PageCompiler/src/CodeWriter.cpp#1 $ // $Id: //poco/1.3/PageCompiler/src/CodeWriter.cpp#1 $
// //
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. // Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
// and Contributors. // and Contributors.
// //
// Permission is hereby granted, free of charge, to any person or organization // Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by // obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute, // this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the // 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 // Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following: // do so, all subject to the following:
// //
// The copyright notices in the Software and this entire statement, including // The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer, // 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 // 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 // all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by // works are solely in the form of machine-executable object code generated by
// a source language processor. // a source language processor.
// //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, // 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 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
// //
#include "CodeWriter.h" #include "CodeWriter.h"
#include "Page.h" #include "Page.h"
#include "Poco/Path.h" #include "Poco/Path.h"
#include "Poco/StringTokenizer.h" #include "Poco/StringTokenizer.h"
using Poco::Path; using Poco::Path;
using Poco::StringTokenizer; using Poco::StringTokenizer;
CodeWriter::CodeWriter(const Page& page, const std::string& clazz): CodeWriter::CodeWriter(const Page& page, const std::string& clazz):
_page(page), _page(page),
_class(clazz) _class(clazz)
{ {
} }
CodeWriter::~CodeWriter() CodeWriter::~CodeWriter()
{ {
} }
void CodeWriter::writeHeader(std::ostream& ostr, const std::string& headerFileName) void CodeWriter::writeHeader(std::ostream& ostr, const std::string& headerFileName)
{ {
beginGuard(ostr, headerFileName); beginGuard(ostr, headerFileName);
writeHeaderIncludes(ostr); writeHeaderIncludes(ostr);
ostr << "\n\n"; ostr << "\n\n";
std::string decls(_page.headerDecls().str()); std::string decls(_page.headerDecls().str());
if (!decls.empty()) if (!decls.empty())
{ {
ostr << decls << "\n\n"; ostr << decls << "\n\n";
} }
beginNamespace(ostr); beginNamespace(ostr);
writeHandlerClass(ostr); writeHandlerClass(ostr);
writeFactoryClass(ostr); writeFactoryClass(ostr);
endNamespace(ostr); endNamespace(ostr);
endGuard(ostr, headerFileName); endGuard(ostr, headerFileName);
} }
void CodeWriter::writeImpl(std::ostream& ostr, const std::string& headerFileName) void CodeWriter::writeImpl(std::ostream& ostr, const std::string& headerFileName)
{ {
ostr << "#include \"" << headerFileName << "\"\n"; ostr << "#include \"" << headerFileName << "\"\n";
writeImplIncludes(ostr); writeImplIncludes(ostr);
ostr << "\n\n"; ostr << "\n\n";
std::string decls(_page.implDecls().str()); std::string decls(_page.implDecls().str());
if (!decls.empty()) if (!decls.empty())
{ {
ostr << decls << "\n\n"; ostr << decls << "\n\n";
} }
beginNamespace(ostr); beginNamespace(ostr);
writeConstructor(ostr); writeConstructor(ostr);
writeHandler(ostr); writeHandler(ostr);
writeFactory(ostr); writeFactory(ostr);
endNamespace(ostr); endNamespace(ostr);
writeManifest(ostr); writeManifest(ostr);
} }
void CodeWriter::beginNamespace(std::ostream& ostr) void CodeWriter::beginNamespace(std::ostream& ostr)
{ {
std::string ns = _page.get("page.namespace", ""); std::string ns = _page.get("page.namespace", "");
if (!ns.empty()) if (!ns.empty())
{ {
StringTokenizer tok(ns, ":", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM); StringTokenizer tok(ns, ":", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
for (StringTokenizer::Iterator it = tok.begin(); it != tok.end(); ++it) for (StringTokenizer::Iterator it = tok.begin(); it != tok.end(); ++it)
{ {
ostr << "namespace " << *it << " {\n"; ostr << "namespace " << *it << " {\n";
} }
ostr << "\n\n"; ostr << "\n\n";
} }
} }
void CodeWriter::endNamespace(std::ostream& ostr) void CodeWriter::endNamespace(std::ostream& ostr)
{ {
std::string ns = _page.get("page.namespace", ""); std::string ns = _page.get("page.namespace", "");
if (!ns.empty()) if (!ns.empty())
{ {
ostr << "\n\n"; ostr << "\n\n";
StringTokenizer tok(ns, ":", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM); StringTokenizer tok(ns, ":", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
for (StringTokenizer::Iterator it = tok.begin(); it != tok.end(); ++it) for (StringTokenizer::Iterator it = tok.begin(); it != tok.end(); ++it)
{ {
ostr << "} "; ostr << "} ";
} }
ostr << "// namespace " << ns << "\n"; ostr << "// namespace " << ns << "\n";
} }
} }
void CodeWriter::beginGuard(std::ostream& ostr, const std::string& headerFileName) void CodeWriter::beginGuard(std::ostream& ostr, const std::string& headerFileName)
{ {
Path p(headerFileName); Path p(headerFileName);
std::string guard(p.getBaseName()); std::string guard(p.getBaseName());
guard += "_INCLUDED"; guard += "_INCLUDED";
ostr << "#ifndef " << guard << "\n"; ostr << "#ifndef " << guard << "\n";
ostr << "#define " << guard << "\n"; ostr << "#define " << guard << "\n";
ostr << "\n\n"; ostr << "\n\n";
} }
void CodeWriter::endGuard(std::ostream& ostr, const std::string& headerFileName) void CodeWriter::endGuard(std::ostream& ostr, const std::string& headerFileName)
{ {
Path p(headerFileName); Path p(headerFileName);
std::string guard(p.getBaseName()); std::string guard(p.getBaseName());
guard += "_INCLUDED"; guard += "_INCLUDED";
ostr << "\n\n"; ostr << "\n\n";
ostr << "#endif // " << guard << "\n"; ostr << "#endif // " << guard << "\n";
} }
void CodeWriter::handlerClass(std::ostream& ostr, const std::string& base, const std::string& ctorArg) void CodeWriter::handlerClass(std::ostream& ostr, const std::string& base, const std::string& ctorArg)
{ {
std::string exprt(_page.get("page.export", "")); std::string exprt(_page.get("page.export", ""));
if (!exprt.empty()) exprt += ' '; if (!exprt.empty()) exprt += ' ';
ostr << "class " << exprt << _class << ": public " << base << "\n"; ostr << "class " << exprt << _class << ": public " << base << "\n";
ostr << "{\n"; ostr << "{\n";
ostr << "public:\n"; ostr << "public:\n";
if (!ctorArg.empty()) if (!ctorArg.empty())
{ {
ostr << "\t" << _class << "(" << ctorArg << ");\n"; ostr << "\t" << _class << "(" << ctorArg << ");\n";
ostr << "\n"; ostr << "\n";
} }
ostr << "\tvoid handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response);\n"; ostr << "\tvoid handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response);\n";
writeHandlerMembers(ostr); writeHandlerMembers(ostr);
ostr << "};\n"; ostr << "};\n";
} }
void CodeWriter::factoryClass(std::ostream& ostr, const std::string& base) void CodeWriter::factoryClass(std::ostream& ostr, const std::string& base)
{ {
ostr << "class " << _class << "Factory: public " << base << "\n"; ostr << "class " << _class << "Factory: public " << base << "\n";
ostr << "{\n"; ostr << "{\n";
ostr << "public:\n"; ostr << "public:\n";
ostr << "\tPoco::Net::HTTPRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request);\n"; ostr << "\tPoco::Net::HTTPRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request);\n";
ostr << "};\n"; ostr << "};\n";
} }
void CodeWriter::factoryImpl(std::ostream& ostr, const std::string& arg) void CodeWriter::factoryImpl(std::ostream& ostr, const std::string& arg)
{ {
ostr << "Poco::Net::HTTPRequestHandler* " << _class << "Factory::createRequestHandler(const Poco::Net::HTTPServerRequest& request)\n"; ostr << "Poco::Net::HTTPRequestHandler* " << _class << "Factory::createRequestHandler(const Poco::Net::HTTPServerRequest& request)\n";
ostr << "{\n"; ostr << "{\n";
ostr << "\treturn new " << _class << "(" << arg << ");\n"; ostr << "\treturn new " << _class << "(" << arg << ");\n";
ostr << "}\n"; ostr << "}\n";
} }
void CodeWriter::writeHeaderIncludes(std::ostream& ostr) void CodeWriter::writeHeaderIncludes(std::ostream& ostr)
{ {
ostr << "#include \"Poco/Net/HTTPRequestHandler.h\"\n"; ostr << "#include \"Poco/Net/HTTPRequestHandler.h\"\n";
} }
void CodeWriter::writeHandlerClass(std::ostream& ostr) void CodeWriter::writeHandlerClass(std::ostream& ostr)
{ {
std::string base(_page.get("page.baseClass", "Poco::Net::HTTPRequestHandler")); std::string base(_page.get("page.baseClass", "Poco::Net::HTTPRequestHandler"));
std::string ctorArg; std::string ctorArg;
ctorArg = _page.get("page.ctorArg", ""); ctorArg = _page.get("page.ctorArg", "");
handlerClass(ostr, base, ctorArg); handlerClass(ostr, base, ctorArg);
} }
void CodeWriter::writeHandlerMembers(std::ostream& ostr) void CodeWriter::writeHandlerMembers(std::ostream& ostr)
{ {
} }
void CodeWriter::writeFactoryClass(std::ostream& ostr) void CodeWriter::writeFactoryClass(std::ostream& ostr)
{ {
} }
void CodeWriter::writeImplIncludes(std::ostream& ostr) void CodeWriter::writeImplIncludes(std::ostream& ostr)
{ {
ostr << "#include \"Poco/Net/HTTPServerRequest.h\"\n"; ostr << "#include \"Poco/Net/HTTPServerRequest.h\"\n";
ostr << "#include \"Poco/Net/HTTPServerResponse.h\"\n"; ostr << "#include \"Poco/Net/HTTPServerResponse.h\"\n";
ostr << "#include \"Poco/Net/HTMLForm.h\"\n"; ostr << "#include \"Poco/Net/HTMLForm.h\"\n";
} }
void CodeWriter::writeConstructor(std::ostream& ostr) void CodeWriter::writeConstructor(std::ostream& ostr)
{ {
std::string base(_page.get("page.baseClass", "Poco::Net::HTTPRequestHandler")); std::string base(_page.get("page.baseClass", "Poco::Net::HTTPRequestHandler"));
std::string ctorArg(_page.get("page.ctorArg", "")); std::string ctorArg(_page.get("page.ctorArg", ""));
if (!ctorArg.empty()) if (!ctorArg.empty())
{ {
ostr << _class << "::" << _class << "(" << ctorArg << " arg):\n"; ostr << _class << "::" << _class << "(" << ctorArg << " arg):\n";
ostr << "\t" << base << "(arg)\n"; ostr << "\t" << base << "(arg)\n";
ostr << "{\n}\n"; ostr << "{\n}\n";
ostr << "\n\n"; ostr << "\n\n";
} }
} }
void CodeWriter::writeHandler(std::ostream& ostr) void CodeWriter::writeHandler(std::ostream& ostr)
{ {
ostr << "void " << _class << "::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response)\n"; ostr << "void " << _class << "::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response)\n";
ostr << "{\n"; ostr << "{\n";
writeSession(ostr); if (_page.has("page.precondition"))
writeForm(ostr); {
writeRequest(ostr); ostr << "\tif (!(" << _page.get("page.precondition") << ")) return;\n\n";
ostr << _page.handler().str(); }
ostr << "}\n"; writeSession(ostr);
} writeForm(ostr);
writeRequest(ostr);
ostr << _page.handler().str();
void CodeWriter::writeFactory(std::ostream& ostr) ostr << "}\n";
{ }
}
void CodeWriter::writeFactory(std::ostream& ostr)
void CodeWriter::writeManifest(std::ostream& ostr) {
{ }
}
void CodeWriter::writeManifest(std::ostream& ostr)
void CodeWriter::writeSession(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", "")); void CodeWriter::writeForm(std::ostream& ostr)
if (!partHandler.empty()) {
{ if (_page.get("page.form", "true") != "false")
ostr << "\t" << partHandler << " cpspPartHandler(*this);\n"; {
} std::string partHandler(_page.get("page.formPartHandler", ""));
ostr << "\tPoco::Net::HTMLForm form(request, request.stream()"; if (!partHandler.empty())
if (!partHandler.empty()) {
{ ostr << "\t" << partHandler << " cpspPartHandler(*this);\n";
ostr << ", cpspPartHandler"; }
} ostr << "\tPoco::Net::HTMLForm form(request, request.stream()";
ostr << ");\n"; 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"));
void CodeWriter::writeRequest(std::ostream& ostr)
if (chunked != "false") {
{ std::string contentType(_page.get("page.contentType", "text/html"));
ostr << "\tresponse.setChunkedTransferEncoding(true);\n"; std::string chunked(_page.get("page.chunked", "true"));
}
if (chunked != "false")
ostr << "\tresponse.setContentType(\"" << contentType << "\");\n"; {
ostr << "\n"; ostr << "\tresponse.setChunkedTransferEncoding(true);\n";
ostr << "\tstd::ostream& ostr = response.send();\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";
}

View File

@ -1,115 +1,115 @@
// //
// CodeWriter.h // CodeWriter.h
// //
// $Id: //poco/Main/PageCompiler/src/CodeWriter.h#1 $ // $Id: //poco/1.3/PageCompiler/src/CodeWriter.h#1 $
// //
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. // Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
// and Contributors. // and Contributors.
// //
// Permission is hereby granted, free of charge, to any person or organization // Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by // obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute, // this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the // 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 // Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following: // do so, all subject to the following:
// //
// The copyright notices in the Software and this entire statement, including // The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer, // 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 // 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 // all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by // works are solely in the form of machine-executable object code generated by
// a source language processor. // a source language processor.
// //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, // 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 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
// //
#ifndef CodeWriter_INCLUDED #ifndef CodeWriter_INCLUDED
#define CodeWriter_INCLUDED #define CodeWriter_INCLUDED
#include "Poco/Poco.h" #include "Poco/Poco.h"
#include <ostream> #include <ostream>
class Page; class Page;
class CodeWriter class CodeWriter
/// This class implements the code generator for /// This class implements the code generator for
/// generating C++ header and implementation files /// generating C++ header and implementation files
/// from C++ Server Pages. /// from C++ Server Pages.
{ {
public: public:
CodeWriter(const Page& page, const std::string& clazz); CodeWriter(const Page& page, const std::string& clazz);
/// Creates the CodeWriter, using the given Page. /// Creates the CodeWriter, using the given Page.
~CodeWriter(); virtual ~CodeWriter();
/// Destroys the PageReader. /// Destroys the PageReader.
virtual void writeHeader(std::ostream& ostr, const std::string& headerFileName); virtual void writeHeader(std::ostream& ostr, const std::string& headerFileName);
/// Writes the header file contents to the given stream. /// Writes the header file contents to the given stream.
virtual void writeImpl(std::ostream& ostr, const std::string& headerFileName); virtual void writeImpl(std::ostream& ostr, const std::string& headerFileName);
/// Writes the implementation file contents to the given stream. /// Writes the implementation file contents to the given stream.
const Page& page() const; const Page& page() const;
/// Returns a const reference to the Page. /// Returns a const reference to the Page.
const std::string& clazz() const; const std::string& clazz() const;
/// Returns the name of the handler class. /// Returns the name of the handler class.
protected: protected:
virtual void writeHeaderIncludes(std::ostream& ostr); virtual void writeHeaderIncludes(std::ostream& ostr);
virtual void writeHandlerClass(std::ostream& ostr); virtual void writeHandlerClass(std::ostream& ostr);
virtual void writeHandlerMembers(std::ostream& ostr); virtual void writeHandlerMembers(std::ostream& ostr);
virtual void writeFactoryClass(std::ostream& ostr); virtual void writeFactoryClass(std::ostream& ostr);
virtual void writeImplIncludes(std::ostream& ostr); virtual void writeImplIncludes(std::ostream& ostr);
virtual void writeConstructor(std::ostream& ostr); virtual void writeConstructor(std::ostream& ostr);
virtual void writeHandler(std::ostream& ostr); virtual void writeHandler(std::ostream& ostr);
virtual void writeFactory(std::ostream& ostr); virtual void writeFactory(std::ostream& ostr);
virtual void writeSession(std::ostream& ostr); virtual void writeSession(std::ostream& ostr);
virtual void writeForm(std::ostream& ostr); virtual void writeForm(std::ostream& ostr);
virtual void writeRequest(std::ostream& ostr); virtual void writeRequest(std::ostream& ostr);
virtual void writeManifest(std::ostream& ostr); virtual void writeManifest(std::ostream& ostr);
void beginGuard(std::ostream& ostr, const std::string& headerFileName); void beginGuard(std::ostream& ostr, const std::string& headerFileName);
void endGuard(std::ostream& ostr, const std::string& headerFileName); void endGuard(std::ostream& ostr, const std::string& headerFileName);
void beginNamespace(std::ostream& ostr); void beginNamespace(std::ostream& ostr);
void endNamespace(std::ostream& ostr); void endNamespace(std::ostream& ostr);
void handlerClass(std::ostream& ostr, const std::string& base, const std::string& ctorArg); void handlerClass(std::ostream& ostr, const std::string& base, const std::string& ctorArg);
void factoryClass(std::ostream& ostr, const std::string& base); void factoryClass(std::ostream& ostr, const std::string& base);
void factoryImpl(std::ostream& ostr, const std::string& arg); void factoryImpl(std::ostream& ostr, const std::string& arg);
private: private:
CodeWriter(); CodeWriter();
CodeWriter(const CodeWriter&); CodeWriter(const CodeWriter&);
CodeWriter& operator = (const CodeWriter&); CodeWriter& operator = (const CodeWriter&);
const Page& _page; const Page& _page;
std::string _class; std::string _class;
}; };
// //
// inlines // inlines
// //
inline const Page& CodeWriter::page() const inline const Page& CodeWriter::page() const
{ {
return _page; return _page;
} }
inline const std::string& CodeWriter::clazz() const inline const std::string& CodeWriter::clazz() const
{ {
return _class; return _class;
} }
#endif // CodeWriter_INCLUDED #endif // CodeWriter_INCLUDED