updated PageCompiler

This commit is contained in:
Guenter Obiltschnig 2012-10-13 10:07:17 +00:00
parent 045c23a9f6
commit 8f00fdb78a
7 changed files with 196 additions and 48 deletions

View File

@ -1,7 +1,7 @@
// //
// File2Page.cpp // File2Page.cpp
// //
// $Id: //poco/1.4/PageCompiler/File2Page/src/File2Page.cpp#3 $ // $Id: //poco/1.4/PageCompiler/File2Page/src/File2Page.cpp#4 $
// //
// An application that creates a Page Compiler source file from an // An application that creates a Page Compiler source file from an
// ordinary file. // ordinary file.
@ -88,46 +88,53 @@ protected:
Application::defineOptions(options); Application::defineOptions(options);
options.addOption( options.addOption(
Option("help", "h", "display help information on command line arguments") Option("help", "h", "Display help information on command line arguments.")
.required(false) .required(false)
.repeatable(false) .repeatable(false)
.callback(OptionCallback<File2PageApp>(this, &File2PageApp::handleHelp))); .callback(OptionCallback<File2PageApp>(this, &File2PageApp::handleHelp)));
options.addOption( options.addOption(
Option("contentType", "t", "specify a content type") Option("contentType", "t", "Specify a content type.")
.required(false) .required(false)
.repeatable(false) .repeatable(false)
.argument("MIME-Type") .argument("MIME-Type")
.callback(OptionCallback<File2PageApp>(this, &File2PageApp::handleContentType))); .callback(OptionCallback<File2PageApp>(this, &File2PageApp::handleContentType)));
options.addOption( options.addOption(
Option("contentLanguage", "l", "specify a content language") Option("contentLanguage", "l", "Specify a content language.")
.required(false) .required(false)
.repeatable(false) .repeatable(false)
.argument("language") .argument("language")
.callback(OptionCallback<File2PageApp>(this, &File2PageApp::handleContentLang))); .callback(OptionCallback<File2PageApp>(this, &File2PageApp::handleContentLang)));
options.addOption( options.addOption(
Option("class", "c", "specify the handler class name") Option("class", "c", "Specify the handler class name.")
.required(false) .required(false)
.repeatable(false) .repeatable(false)
.argument("class-name") .argument("class-name")
.callback(OptionCallback<File2PageApp>(this, &File2PageApp::handleClassName))); .callback(OptionCallback<File2PageApp>(this, &File2PageApp::handleClassName)));
options.addOption( options.addOption(
Option("namespace", "n", "specify the handler class namespace name") Option("namespace", "n", "Specify the handler class namespace name.")
.required(false) .required(false)
.repeatable(false) .repeatable(false)
.argument("namespace-name") .argument("namespace-name")
.callback(OptionCallback<File2PageApp>(this, &File2PageApp::handleNamespace))); .callback(OptionCallback<File2PageApp>(this, &File2PageApp::handleNamespace)));
options.addOption( options.addOption(
Option("output", "o", "specify the output file name") Option("output", "o", "Specify the output file name.")
.required(false) .required(false)
.repeatable(false) .repeatable(false)
.argument("path") .argument("path")
.callback(OptionCallback<File2PageApp>(this, &File2PageApp::handleOutput))); .callback(OptionCallback<File2PageApp>(this, &File2PageApp::handleOutput)));
}
options.addOption(
Option("path", "p", "Specify the server path of the file.")
.required(false)
.repeatable(false)
.argument("path")
.callback(OptionCallback<File2PageApp>(this, &File2PageApp::handlePath)));
}
void handleHelp(const std::string& name, const std::string& value) void handleHelp(const std::string& name, const std::string& value)
{ {
@ -161,12 +168,18 @@ protected:
_output = value; _output = value;
} }
void handlePath(const std::string& name, const std::string& value)
{
_path = value;
}
void displayHelp() void displayHelp()
{ {
HelpFormatter helpFormatter(options()); HelpFormatter helpFormatter(options());
helpFormatter.setCommand(commandName()); helpFormatter.setCommand(commandName());
helpFormatter.setUsage("OPTIONS"); helpFormatter.setUsage("OPTIONS");
helpFormatter.setHeader("Create a PageCompiler source file from a binary file."); helpFormatter.setHeader("Create a PageCompiler source file from a binary file.");
helpFormatter.setIndent(8);
helpFormatter.format(std::cout); helpFormatter.format(std::cout);
} }
@ -200,8 +213,12 @@ protected:
} }
ostr << " form=\"false\"\n" ostr << " form=\"false\"\n"
<< " namespace=\"" << _namespace << "\"\n" << " namespace=\"" << _namespace << "\"\n"
<< " class=\"" << _clazz << "\"\n" << " class=\"" << _clazz << "\"\n";
<< " precondition=\"checkModified(request)\"%><%@" if (!_path.empty())
{
ostr << " path=\"" << _path << "\"\n";
}
ostr << " precondition=\"checkModified(request)\"%><%@"
<< " impl include=\"Poco/DateTime.h\"\n" << " impl include=\"Poco/DateTime.h\"\n"
<< " include=\"Poco/DateTimeParser.h\"\n" << " include=\"Poco/DateTimeParser.h\"\n"
<< " include=\"Poco/DateTimeFormatter.h\"\n" << " include=\"Poco/DateTimeFormatter.h\"\n"
@ -292,6 +309,7 @@ private:
std::string _clazz; std::string _clazz;
std::string _namespace; std::string _namespace;
std::string _output; std::string _output;
std::string _path;
}; };

View File

@ -245,6 +245,28 @@ Allows you to specify whether the response is sent using chunked transfer encodi
Defaults to <[true]>. Defaults to <[true]>.
Set the value to <[false]> to disable chunked transfer encoding. Set the value to <[false]> to disable chunked transfer encoding.
!compressed
Enables or disables response body compression. If set to <[true]>, and the client supports
the "gzip" content encoding (indicated by the "Accept-Encoding" header),
the response body will be compressed using the "gzip" format and the
"Content-Encoding" header will be set accordingly.
Defaults to <[false]>. Cannot be enabled together with response buffering.
!compressionLevel
Specify the compression level, if response body compression is enabled.
Valid values are 1 (fastest) to 9 (best compression). Defaults to 1.
!buffered
Enables or disables response buffering. Response buffering is disabled by default.
Set to <[true]> to enable buffering, or to <[false]> to disable it.
If response buffering is enabled, everything written to the response stream
is actually written to a string stream (<[std::ostringstream]>).
Sending of the HTTP response back to the client is deferred to
when the page is complete.
!session (OSP only) !session (OSP only)
For use with the POCO Open Service Platform only. For use with the POCO Open Service Platform only.
@ -273,15 +295,6 @@ a new session will be created if the request does not contain a (valid) session
If set to <[false]> and there is no existing session that matches the session If set to <[false]> and there is no existing session that matches the session
cookie. the <[session]> variable will be null. cookie. the <[session]> variable will be null.
!buffered
Enables or disables response buffering. Response buffering is disabled by default.
Set to <[true]> to enable buffering, or to <[false]> to disable it.
If response buffering is enabled, everything written to the response stream
is actually written to a string stream (<[std::ostringstream]>).
Sending of the HTTP response back to the client is deferred to
when the page is complete.
!precondition !precondition
Allows to specify a C++ boolean expression which will be evaluated before processing Allows to specify a C++ boolean expression which will be evaluated before processing
@ -295,6 +308,17 @@ Example:
<%@ page precondition="checkCredentials(request, response)" %> <%@ page precondition="checkCredentials(request, response)" %>
---- ----
!path
Specify a server path for the page. If specified, the generated handler class
will contain a public static <[const std::string]> member variable named <[PATH]>
containing the specified path.
Example:
<%@ page path="/index.html" %>
----
!!Implicit Objects !!Implicit Objects
The following objects are available in the handler code. The following objects are available in the handler code.

View File

@ -1,7 +1,7 @@
// //
// CodeWriter.cpp // CodeWriter.cpp
// //
// $Id: //poco/1.4/PageCompiler/src/CodeWriter.cpp#2 $ // $Id: //poco/1.4/PageCompiler/src/CodeWriter.cpp#3 $
// //
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. // Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
// and Contributors. // and Contributors.
@ -34,6 +34,7 @@
#include "Page.h" #include "Page.h"
#include "Poco/Path.h" #include "Poco/Path.h"
#include "Poco/StringTokenizer.h" #include "Poco/StringTokenizer.h"
#include "Poco/String.h"
using Poco::Path; using Poco::Path;
@ -76,6 +77,10 @@ void CodeWriter::writeImpl(std::ostream& ostr, const std::string& headerFileName
{ {
ostr << "#include \"" << headerFileName << "\"\n"; ostr << "#include \"" << headerFileName << "\"\n";
writeImplIncludes(ostr); writeImplIncludes(ostr);
if (_page.getBool("page.compressed", false))
{
ostr << "#include \"Poco/DeflatingStream.h\"\n";
}
if (_page.getBool("page.buffered", false)) if (_page.getBool("page.buffered", false))
{ {
ostr << "#include \"Poco/StreamCopier.h\"\n"; ostr << "#include \"Poco/StreamCopier.h\"\n";
@ -90,6 +95,13 @@ void CodeWriter::writeImpl(std::ostream& ostr, const std::string& headerFileName
} }
beginNamespace(ostr); beginNamespace(ostr);
std::string path = _page.get("page.path", "");
if (!path.empty())
{
ostr << "\tconst std::string " << _class << "::PATH(\"" << path << "\");\n\n\n";
}
writeConstructor(ostr); writeConstructor(ostr);
writeHandler(ostr); writeHandler(ostr);
writeFactory(ostr); writeFactory(ostr);
@ -132,7 +144,9 @@ void CodeWriter::beginGuard(std::ostream& ostr, const std::string& headerFileNam
{ {
Path p(headerFileName); Path p(headerFileName);
std::string guard(p.getBaseName()); std::string guard(p.getBaseName());
Poco::translateInPlace(guard, ".-", "__");
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";
@ -143,6 +157,7 @@ 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());
Poco::translateInPlace(guard, ".-", "__");
guard += "_INCLUDED"; guard += "_INCLUDED";
ostr << "\n\n"; ostr << "\n\n";
ostr << "#endif // " << guard << "\n"; ostr << "#endif // " << guard << "\n";
@ -164,6 +179,13 @@ void CodeWriter::handlerClass(std::ostream& ostr, const std::string& base, const
} }
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);
std::string path = _page.get("page.path", "");
if (!path.empty())
{
ostr << "\n\tstatic const std::string PATH;\n";
}
ostr << "};\n"; ostr << "};\n";
} }
@ -313,7 +335,10 @@ void CodeWriter::writeResponse(std::ostream& ostr)
std::string contentLang(_page.get("page.contentLanguage", "")); std::string contentLang(_page.get("page.contentLanguage", ""));
bool buffered(_page.getBool("page.buffered", false)); bool buffered(_page.getBool("page.buffered", false));
bool chunked(_page.getBool("page.chunked", !buffered)); bool chunked(_page.getBool("page.chunked", !buffered));
bool compressed(_page.getBool("page.compressed", false));
if (buffered) compressed = false;
if (compressed) chunked = true;
if (chunked) if (chunked)
{ {
ostr << "\tresponse.setChunkedTransferEncoding(true);\n"; ostr << "\tresponse.setChunkedTransferEncoding(true);\n";
@ -325,6 +350,11 @@ void CodeWriter::writeResponse(std::ostream& ostr)
ostr << "\tif (request.has(\"Accept-Language\"))\n" ostr << "\tif (request.has(\"Accept-Language\"))\n"
<< "\t\tresponse.set(\"Content-Language\", \"" << contentLang << "\");\n"; << "\t\tresponse.set(\"Content-Language\", \"" << contentLang << "\");\n";
} }
if (compressed)
{
ostr << "\tbool _compressResponse(request.hasToken(\"Accept-Encoding\", \"gzip\"));\n"
<< "\tif (_compressResponse) response.set(\"Content-Encoding\", \"gzip\");\n";
}
ostr << "\n"; ostr << "\n";
} }
@ -333,6 +363,10 @@ void CodeWriter::writeContent(std::ostream& ostr)
{ {
bool buffered(_page.getBool("page.buffered", false)); bool buffered(_page.getBool("page.buffered", false));
bool chunked(_page.getBool("page.chunked", !buffered)); bool chunked(_page.getBool("page.chunked", !buffered));
bool compressed(_page.getBool("page.compressed", false));
int compressionLevel(_page.getInt("page.compressionLevel", 1));
if (buffered) compressed = false;
if (compressed) chunked = true;
if (buffered) if (buffered)
{ {
@ -344,6 +378,14 @@ void CodeWriter::writeContent(std::ostream& ostr)
} }
ostr << "\tPoco::StreamCopier::copyStream(responseStream, response.send());\n"; ostr << "\tPoco::StreamCopier::copyStream(responseStream, response.send());\n";
} }
else if (compressed)
{
ostr << "\tstd::ostream& _responseStream = response.send();\n"
<< "\tPoco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, " << compressionLevel << ");\n"
<< "\tstd::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream;\n";
ostr << _page.handler().str();
ostr << "\tif (_compressResponse) _gzipStream.close();\n";
}
else else
{ {
ostr << "\tstd::ostream& responseStream = response.send();\n"; ostr << "\tstd::ostream& responseStream = response.send();\n";

View File

@ -1,7 +1,7 @@
// //
// OSPCodeWriter.cpp // OSPCodeWriter.cpp
// //
// $Id: //poco/1.4/PageCompiler/src/OSPCodeWriter.cpp#2 $ // $Id: //poco/1.4/PageCompiler/src/OSPCodeWriter.cpp#3 $
// //
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. // Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
// and Contributors. // and Contributors.
@ -64,15 +64,19 @@ void OSPCodeWriter::writeHandlerClass(std::ostream& ostr)
void OSPCodeWriter::writeHandlerMembers(std::ostream& ostr) void OSPCodeWriter::writeHandlerMembers(std::ostream& ostr)
{ {
ostr << "\n"; std::string base(page().get("page.baseClass", ""));
ostr << "protected:\n"; if (base.empty())
ostr << "\tPoco::OSP::BundleContext::Ptr context() const\n"; {
ostr << "\t{\n"; ostr << "\n";
ostr << "\t\treturn _pContext;\n"; ostr << "protected:\n";
ostr << "\t}\n"; ostr << "\tPoco::OSP::BundleContext::Ptr context() const\n";
ostr << "\n"; ostr << "\t{\n";
ostr << "private:\n"; ostr << "\t\treturn _pContext;\n";
ostr << "\tPoco::OSP::BundleContext::Ptr _pContext;\n"; ostr << "\t}\n";
ostr << "\n";
ostr << "private:\n";
ostr << "\tPoco::OSP::BundleContext::Ptr _pContext;\n";
}
} }
@ -97,9 +101,16 @@ void OSPCodeWriter::writeImplIncludes(std::ostream& ostr)
void OSPCodeWriter::writeConstructor(std::ostream& ostr) void OSPCodeWriter::writeConstructor(std::ostream& ostr)
{ {
std::string base(page().get("page.baseClass", "Poco::Net::HTTPRequestHandler")); std::string base(page().get("page.baseClass", ""));
ostr << clazz() << "::" << clazz() << "(Poco::OSP::BundleContext::Ptr pContext):\n"; ostr << clazz() << "::" << clazz() << "(Poco::OSP::BundleContext::Ptr pContext):\n";
ostr << "\t_pContext(pContext)\n"; if (base.empty())
{
ostr << "\t_pContext(pContext)\n";
}
else
{
ostr << "\t" << base << "(pContext)\n";
}
ostr << "{\n}\n"; ostr << "{\n}\n";
ostr << "\n\n"; ostr << "\n\n";
} }

View File

@ -1,7 +1,7 @@
// //
// Page.cpp // Page.cpp
// //
// $Id: //poco/1.4/PageCompiler/src/Page.cpp#1 $ // $Id: //poco/1.4/PageCompiler/src/Page.cpp#2 $
// //
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. // Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
// and Contributors. // and Contributors.
@ -32,6 +32,7 @@
#include "Page.h" #include "Page.h"
#include "Poco/String.h" #include "Poco/String.h"
#include "Poco/NumberParser.h"
Page::Page() Page::Page()
@ -55,3 +56,13 @@ bool Page::getBool(const std::string& property, bool deflt) const
} }
else return deflt; else return deflt;
} }
int Page::getInt(const std::string& property, int deflt) const
{
if (has(property))
{
return Poco::NumberParser::parse(get(property));
}
else return deflt;
}

View File

@ -1,7 +1,7 @@
// //
// Page.h // Page.h
// //
// $Id: //poco/1.4/PageCompiler/src/Page.h#1 $ // $Id: //poco/1.4/PageCompiler/src/Page.h#2 $
// //
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH. // Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
// and Contributors. // and Contributors.
@ -84,6 +84,9 @@ public:
/// ///
/// Otherwise, the return value will be false. /// Otherwise, the return value will be false.
int getInt(const std::string& property, int deflt = 0) const;
/// Returns the integer value of the given property.
private: private:
Page(const Page&); Page(const Page&);
Page& operator = (const Page&); Page& operator = (const Page&);

View File

@ -1,7 +1,7 @@
// //
// PageCompiler.cpp // PageCompiler.cpp
// //
// $Id: //poco/1.4/PageCompiler/src/PageCompiler.cpp#3 $ // $Id: //poco/1.4/PageCompiler/src/PageCompiler.cpp#4 $
// //
// A compiler that compiler HTML pages containing JSP directives into C++ classes. // A compiler that compiler HTML pages containing JSP directives into C++ classes.
// //
@ -139,6 +139,13 @@ protected:
.argument("<prefix>") .argument("<prefix>")
.callback(OptionCallback<CompilerApp>(this, &CompilerApp::handleHeaderPrefix))); .callback(OptionCallback<CompilerApp>(this, &CompilerApp::handleHeaderPrefix)));
options.addOption(
Option("base-file-name", "b", "Use <name> instead of the class name for the output file name.")
.required(false)
.repeatable(false)
.argument("<name>")
.callback(OptionCallback<CompilerApp>(this, &CompilerApp::handleBase)));
options.addOption( options.addOption(
Option("osp", "O", "Add factory class definition and implementation for use with the Open Service Platform.") Option("osp", "O", "Add factory class definition and implementation for use with the Open Service Platform.")
.required(false) .required(false)
@ -191,6 +198,11 @@ protected:
_headerPrefix += '/'; _headerPrefix += '/';
} }
void handleBase(const std::string& name, const std::string& value)
{
_base = value;
}
void handleOSP(const std::string& name, const std::string& value) void handleOSP(const std::string& name, const std::string& value)
{ {
_generateOSPCode = true; _generateOSPCode = true;
@ -205,7 +217,7 @@ protected:
{ {
_emitLineDirectives = false; _emitLineDirectives = false;
} }
void displayHelp() void displayHelp()
{ {
HelpFormatter helpFormatter(options()); HelpFormatter helpFormatter(options());
@ -255,19 +267,32 @@ protected:
{ {
compile(*it); compile(*it);
} }
return Application::EXIT_OK; return Application::EXIT_OK;
} }
void compile(const std::string& path) void parse(const std::string& path, Page& page, std::string& clazz)
{ {
Page page;
FileInputStream srcStream(path); FileInputStream srcStream(path);
PageReader pageReader(page, path); PageReader pageReader(page, path);
pageReader.emitLineDirectives(_emitLineDirectives); pageReader.emitLineDirectives(_emitLineDirectives);
pageReader.parse(srcStream); pageReader.parse(srcStream);
Path p(path);
if (page.has("page.class"))
{
clazz = page.get("page.class");
}
else
{
clazz = p.getBaseName() + "Handler";
clazz[0] = Poco::Ascii::toUpper(clazz[0]);
}
}
void write(const std::string& path, const Page& page, const std::string& clazz)
{
Path p(path); Path p(path);
config().setString("inputFileName", p.getFileName()); config().setString("inputFileName", p.getFileName());
config().setString("inputFilePath", p.toString()); config().setString("inputFilePath", p.toString());
@ -275,17 +300,10 @@ protected:
DateTime now; DateTime now;
config().setString("dateTime", DateTimeFormatter::format(now, DateTimeFormat::SORTABLE_FORMAT)); config().setString("dateTime", DateTimeFormatter::format(now, DateTimeFormat::SORTABLE_FORMAT));
std::string clazz;
if (page.has("page.class")) if (page.has("page.class"))
{ {
clazz = page.get("page.class");
p.setBaseName(clazz); p.setBaseName(clazz);
} }
else
{
clazz = p.getBaseName() + "Handler";
clazz[0] = Poco::Ascii::toUpper(clazz[0]);
}
std::auto_ptr<CodeWriter> pCodeWriter(createCodeWriter(page, clazz)); std::auto_ptr<CodeWriter> pCodeWriter(createCodeWriter(page, clazz));
@ -293,6 +311,12 @@ protected:
{ {
p = Path(_outputDir, p.getBaseName()); p = Path(_outputDir, p.getBaseName());
} }
if (!_base.empty())
{
p.setBaseName(_base);
}
p.setExtension("cpp"); p.setExtension("cpp");
std::string implPath = p.toString(); std::string implPath = p.toString();
std::string implFileName = p.getFileName(); std::string implFileName = p.getFileName();
@ -319,6 +343,20 @@ protected:
writeFileHeader(headerLEC); writeFileHeader(headerLEC);
pCodeWriter->writeHeader(headerLEC, headerFileName); pCodeWriter->writeHeader(headerLEC, headerFileName);
} }
void compile(const std::string& path)
{
Page page;
std::string clazz;
parse(path, page, clazz);
write(path, page, clazz);
FileInputStream srcStream(path);
PageReader pageReader(page, path);
pageReader.emitLineDirectives(_emitLineDirectives);
pageReader.parse(srcStream);
}
void writeFileHeader(std::ostream& ostr) void writeFileHeader(std::ostream& ostr)
{ {
@ -348,6 +386,7 @@ private:
std::string _outputDir; std::string _outputDir;
std::string _headerOutputDir; std::string _headerOutputDir;
std::string _headerPrefix; std::string _headerPrefix;
std::string _base;
}; };