PageCompiler refactoring
This commit is contained in:
Родитель
e045036163
Коммит
3edd579220
|
@ -1,14 +1,16 @@
|
|||
#
|
||||
# Makefile
|
||||
#
|
||||
# $Id: //poco/Main/PageCompiler/Makefile#1 $
|
||||
# $Id: //poco/Main/PageCompiler/Makefile#3 $
|
||||
#
|
||||
# Makefile for Poco C++ Server Page Compiler
|
||||
#
|
||||
|
||||
include $(POCO_BASE)/build/rules/global
|
||||
|
||||
objects = Page PageCompiler
|
||||
objects = Page PageReader \
|
||||
CodeWriter ApacheCodeWriter OSPCodeWriter \
|
||||
PageCompiler
|
||||
|
||||
target = cpspc
|
||||
target_version = 1
|
||||
|
|
|
@ -260,19 +260,43 @@
|
|||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath=".\src\ApacheCodeWriter.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\CodeWriter.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\OSPCodeWriter.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\Page.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\PageCompiler.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\PageReader.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath=".\src\ApacheCodeWriter.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\CodeWriter.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\OSPCodeWriter.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\Page.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\PageReader.h">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
|
|
|
@ -206,6 +206,18 @@
|
|||
<Filter
|
||||
Name="Source Files"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\src\ApacheCodeWriter.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\CodeWriter.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\OSPCodeWriter.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\Page.cpp"
|
||||
>
|
||||
|
@ -214,14 +226,34 @@
|
|||
RelativePath=".\src\PageCompiler.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\PageReader.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\src\ApacheCodeWriter.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\CodeWriter.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\OSPCodeWriter.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\Page.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\PageReader.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
//
|
||||
// ApacheCodeWriter.cpp
|
||||
//
|
||||
// $Id: //poco/Main/PageCompiler/src/ApacheCodeWriter.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 "ApacheCodeWriter.h"
|
||||
#include "Page.h"
|
||||
|
||||
|
||||
ApacheCodeWriter::ApacheCodeWriter(const Page& page, const std::string& clazz):
|
||||
CodeWriter(page, clazz)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ApacheCodeWriter::~ApacheCodeWriter()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ApacheCodeWriter::writeHeaderIncludes(std::ostream& ostr)
|
||||
{
|
||||
CodeWriter::writeHeaderIncludes(ostr);
|
||||
ostr << "#include \"Poco/Net/HTTPRequestHandlerFactory.h\"\n";
|
||||
}
|
||||
|
||||
|
||||
void ApacheCodeWriter::writeFactoryClass(std::ostream& ostr)
|
||||
{
|
||||
ostr << "\n\n";
|
||||
factoryClass(ostr, "Poco::Net::HTTPRequestHandlerFactory");
|
||||
}
|
||||
|
||||
|
||||
void ApacheCodeWriter::writeImplIncludes(std::ostream& ostr)
|
||||
{
|
||||
CodeWriter::writeImplIncludes(ostr);
|
||||
ostr << "#include \"Poco/ClassLibrary.h\"\n";
|
||||
}
|
||||
|
||||
|
||||
void ApacheCodeWriter::writeFactory(std::ostream& ostr)
|
||||
{
|
||||
ostr << "\n\n";
|
||||
factoryImpl(ostr, "");
|
||||
}
|
||||
|
||||
|
||||
void ApacheCodeWriter::writeManifest(std::ostream& ostr)
|
||||
{
|
||||
std::string ns = page().get("page.namespace", "");
|
||||
if (!ns.empty()) ns += "::";
|
||||
ostr << "\n\n";
|
||||
ostr << "POCO_BEGIN_MANIFEST(Poco::Net::HTTPRequestHandlerFactory)\n";
|
||||
ostr << "\tPOCO_EXPORT_CLASS(" << ns << clazz() << "Factory)\n";
|
||||
ostr << "POCO_END_MANIFEST\n";
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
//
|
||||
// ApacheCodeWriter.h
|
||||
//
|
||||
// $Id: //poco/Main/PageCompiler/src/ApacheCodeWriter.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 ApacheCodeWriter_INCLUDED
|
||||
#define ApacheCodeWriter_INCLUDED
|
||||
|
||||
|
||||
#include "CodeWriter.h"
|
||||
|
||||
|
||||
class ApacheCodeWriter: public CodeWriter
|
||||
/// Code generator for ApacheConnector request handlers.
|
||||
{
|
||||
public:
|
||||
ApacheCodeWriter(const Page& page, const std::string& clazz);
|
||||
/// Creates the CodeWriter, using the given Page.
|
||||
|
||||
~ApacheCodeWriter();
|
||||
/// Destroys the PageReader.
|
||||
|
||||
protected:
|
||||
virtual void writeHeaderIncludes(std::ostream& ostr);
|
||||
virtual void writeFactoryClass(std::ostream& ostr);
|
||||
virtual void writeImplIncludes(std::ostream& ostr);
|
||||
virtual void writeFactory(std::ostream& ostr);
|
||||
virtual void writeManifest(std::ostream& ostr);
|
||||
};
|
||||
|
||||
|
||||
#endif // CodeWriter_INCLUDED
|
|
@ -0,0 +1,292 @@
|
|||
//
|
||||
// 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";
|
||||
}
|
|
@ -0,0 +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 <ostream>
|
||||
|
||||
|
||||
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
|
|
@ -0,0 +1,130 @@
|
|||
//
|
||||
// OSPCodeWriter.cpp
|
||||
//
|
||||
// $Id: //poco/Main/PageCompiler/src/OSPCodeWriter.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 "OSPCodeWriter.h"
|
||||
#include "Page.h"
|
||||
|
||||
|
||||
OSPCodeWriter::OSPCodeWriter(const Page& page, const std::string& clazz):
|
||||
CodeWriter(page, clazz)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
OSPCodeWriter::~OSPCodeWriter()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void OSPCodeWriter::writeHeaderIncludes(std::ostream& ostr)
|
||||
{
|
||||
CodeWriter::writeHeaderIncludes(ostr);
|
||||
ostr << "#include \"Poco/OSP/Web/WebRequestHandlerFactory.h\"\n";
|
||||
ostr << "#include \"Poco/OSP/BundleContext.h\"\n";
|
||||
}
|
||||
|
||||
|
||||
void OSPCodeWriter::writeHandlerClass(std::ostream& ostr)
|
||||
{
|
||||
std::string base(page().get("page.baseClass", "Poco::Net::HTTPRequestHandler"));
|
||||
|
||||
handlerClass(ostr, base, "Poco::OSP::BundleContext::Ptr");
|
||||
}
|
||||
|
||||
|
||||
void OSPCodeWriter::writeHandlerMembers(std::ostream& ostr)
|
||||
{
|
||||
ostr << "\n";
|
||||
ostr << "protected:\n";
|
||||
ostr << "\tPoco::OSP::BundleContext::Ptr context() const\n";
|
||||
ostr << "\t{\n";
|
||||
ostr << "\t\treturn _pContext;\n";
|
||||
ostr << "\t}\n";
|
||||
ostr << "\n";
|
||||
ostr << "private:\n";
|
||||
ostr << "\tPoco::OSP::BundleContext::Ptr _pContext;\n";
|
||||
}
|
||||
|
||||
|
||||
void OSPCodeWriter::writeFactoryClass(std::ostream& ostr)
|
||||
{
|
||||
ostr << "\n\n";
|
||||
factoryClass(ostr, "Poco::OSP::Web::WebRequestHandlerFactory");
|
||||
}
|
||||
|
||||
|
||||
void OSPCodeWriter::writeImplIncludes(std::ostream& ostr)
|
||||
{
|
||||
CodeWriter::writeImplIncludes(ostr);
|
||||
if (page().has("page.session"))
|
||||
{
|
||||
ostr << "#include \"Poco/OSP/Web/WebSession.h\"\n";
|
||||
ostr << "#include \"Poco/OSP/Web/WebSessionManager.h\"\n";
|
||||
ostr << "#include \"Poco/OSP/ServiceRegistry.h\"\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OSPCodeWriter::writeConstructor(std::ostream& ostr)
|
||||
{
|
||||
std::string base(page().get("page.baseClass", "Poco::Net::HTTPRequestHandler"));
|
||||
ostr << clazz() << "::" << clazz() << "(Poco::OSP::BundleContext::Ptr pContext):\n";
|
||||
ostr << "\t_pContext(pContext)\n";
|
||||
ostr << "{\n}\n";
|
||||
ostr << "\n\n";
|
||||
}
|
||||
|
||||
|
||||
void OSPCodeWriter::writeSession(std::ostream& ostr)
|
||||
{
|
||||
if (page().has("page.session"))
|
||||
{
|
||||
ostr << "\tPoco::OSP::Web::WebSession::Ptr session;\n";
|
||||
ostr << "\t{\n";
|
||||
ostr << "\t\tPoco::OSP::ServiceRef::Ptr pWebSessionManagerRef = context()->registry().findByName(Poco::OSP::Web::WebSessionManager::SERVICE_NAME);\n";
|
||||
ostr << "\t\tif (pWebSessionManagerRef)\n";
|
||||
ostr << "\t\t{\n";
|
||||
ostr << "\t\t\tPoco::OSP::Web::WebSessionManager::Ptr pWebSessionManager = pWebSessionManagerRef->castedInstance<Poco::OSP::Web::WebSessionManager>();\n";
|
||||
ostr << "\t\t\tsession = pWebSessionManager->find(\"" << page().get("page.session") << "\", request);\n";
|
||||
ostr << "\t\t\tif (session.isNull())\n";
|
||||
ostr << "\t\t\t\tsession = pWebSessionManager->get(\"" << page().get("page.session") << "\", request, " << page().get("page.sessionTimeout", "30") << ", context());\n";
|
||||
ostr << "\t\t}\n";
|
||||
ostr << "\t}\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OSPCodeWriter::writeFactory(std::ostream& ostr)
|
||||
{
|
||||
ostr << "\n\n";
|
||||
factoryImpl(ostr, "context()");
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
//
|
||||
// OSPCodeWriter.h
|
||||
//
|
||||
// $Id: //poco/Main/PageCompiler/src/OSPCodeWriter.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 OSPCodeWriter_INCLUDED
|
||||
#define OSPCodeWriter_INCLUDED
|
||||
|
||||
|
||||
#include "CodeWriter.h"
|
||||
|
||||
|
||||
class OSPCodeWriter: public CodeWriter
|
||||
/// Code generator for OSP Web request handlers.
|
||||
{
|
||||
public:
|
||||
OSPCodeWriter(const Page& page, const std::string& clazz);
|
||||
/// Creates the CodeWriter, using the given Page.
|
||||
|
||||
~OSPCodeWriter();
|
||||
/// Destroys the PageReader.
|
||||
|
||||
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 writeFactory(std::ostream& ostr);
|
||||
virtual void writeSession(std::ostream& ostr);
|
||||
};
|
||||
|
||||
|
||||
#endif // CodeWriter_INCLUDED
|
|
@ -1,9 +1,9 @@
|
|||
//
|
||||
// Page.cpp
|
||||
//
|
||||
// $Id: //poco/Main/PageCompiler/src/Page.cpp#1 $
|
||||
// $Id: //poco/Main/PageCompiler/src/Page.cpp#2 $
|
||||
//
|
||||
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
||||
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
|
@ -31,327 +31,13 @@
|
|||
|
||||
|
||||
#include "Page.h"
|
||||
#include "Poco/FileStream.h"
|
||||
#include "Poco/CountingStream.h"
|
||||
#include "Poco/Path.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include <sstream>
|
||||
#include <cctype>
|
||||
|
||||
|
||||
const std::string Page::MARKUP_BEGIN("\tostr << \"");
|
||||
const std::string Page::MARKUP_END("\";\n");
|
||||
const std::string Page::EXPR_BEGIN("\tostr << ");
|
||||
const std::string Page::EXPR_END(";\n");
|
||||
|
||||
|
||||
Page::Page(const std::string& basePath)
|
||||
Page::Page()
|
||||
{
|
||||
_headerDecls.reserve(4096);
|
||||
_implDecls.reserve(8192);
|
||||
_paths.push_back(basePath);
|
||||
}
|
||||
|
||||
|
||||
Page::~Page()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Page::addHeaderDecls(const std::string& decls)
|
||||
{
|
||||
_headerDecls.append("\n");
|
||||
_headerDecls.append(decls);
|
||||
}
|
||||
|
||||
|
||||
void Page::addImplDecls(const std::string& decls)
|
||||
{
|
||||
_implDecls.append("\n");
|
||||
_implDecls.append(decls);
|
||||
}
|
||||
|
||||
|
||||
void Page::addAttrs(const std::string& attrs)
|
||||
{
|
||||
_attrs.append(attrs);
|
||||
}
|
||||
|
||||
|
||||
void Page::parse(std::istream& pageStream)
|
||||
{
|
||||
std::ostringstream handlerStream;
|
||||
parse(pageStream, handlerStream);
|
||||
_handler = handlerStream.str();
|
||||
}
|
||||
|
||||
|
||||
void Page::parse(std::istream& pageStream, std::ostream& handlerStream)
|
||||
{
|
||||
ParsingState state = STATE_MARKUP;
|
||||
|
||||
_attrs.clear();
|
||||
handlerStream << MARKUP_BEGIN;
|
||||
|
||||
Poco::CountingInputStream countingPageStream(pageStream);
|
||||
std::string token;
|
||||
nextToken(pageStream, token);
|
||||
while (!token.empty())
|
||||
{
|
||||
if (token == "<%")
|
||||
{
|
||||
if (state == STATE_MARKUP)
|
||||
{
|
||||
handlerStream << MARKUP_END;
|
||||
state = STATE_BLOCK;
|
||||
}
|
||||
else handlerStream << token;
|
||||
}
|
||||
else if (token == "<%!")
|
||||
{
|
||||
if (state == STATE_MARKUP)
|
||||
{
|
||||
handlerStream << MARKUP_END;
|
||||
state = STATE_IMPLDECL;
|
||||
}
|
||||
else handlerStream << token;
|
||||
}
|
||||
else if (token == "<%!!")
|
||||
{
|
||||
if (state == STATE_MARKUP)
|
||||
{
|
||||
handlerStream << MARKUP_END;
|
||||
state = STATE_HDRDECL;
|
||||
}
|
||||
else handlerStream << token;
|
||||
}
|
||||
else if (token == "<%--")
|
||||
{
|
||||
if (state == STATE_MARKUP)
|
||||
{
|
||||
handlerStream << MARKUP_END;
|
||||
state = STATE_COMMENT;
|
||||
}
|
||||
else handlerStream << token;
|
||||
}
|
||||
else if (token == "<%@")
|
||||
{
|
||||
if (state == STATE_MARKUP)
|
||||
{
|
||||
handlerStream << MARKUP_END;
|
||||
state = STATE_ATTR;
|
||||
}
|
||||
else handlerStream << token;
|
||||
}
|
||||
else if (token == "<%=")
|
||||
{
|
||||
if (state == STATE_MARKUP)
|
||||
{
|
||||
handlerStream << MARKUP_END;
|
||||
handlerStream << EXPR_BEGIN;
|
||||
state = STATE_EXPR;
|
||||
}
|
||||
else handlerStream << token;
|
||||
}
|
||||
else if (token == "%>")
|
||||
{
|
||||
if (state == STATE_EXPR)
|
||||
{
|
||||
handlerStream << EXPR_END;
|
||||
handlerStream << MARKUP_BEGIN;
|
||||
state = STATE_MARKUP;
|
||||
}
|
||||
else if (state == STATE_ATTR)
|
||||
{
|
||||
parseAttributes(handlerStream);
|
||||
_attrs.clear();
|
||||
handlerStream << MARKUP_BEGIN;
|
||||
state = STATE_MARKUP;
|
||||
}
|
||||
else if (state != STATE_MARKUP)
|
||||
{
|
||||
handlerStream << MARKUP_BEGIN;
|
||||
state = STATE_MARKUP;
|
||||
}
|
||||
else handlerStream << token;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case STATE_MARKUP:
|
||||
if (token == "\n")
|
||||
{
|
||||
handlerStream << "\\n";
|
||||
handlerStream << MARKUP_END;
|
||||
handlerStream << MARKUP_BEGIN;
|
||||
}
|
||||
else if (token == "\t")
|
||||
{
|
||||
handlerStream << "\\t";
|
||||
}
|
||||
else if (token == "\"")
|
||||
{
|
||||
handlerStream << "\\\"";
|
||||
}
|
||||
else if (token != "\r")
|
||||
{
|
||||
handlerStream << token;
|
||||
}
|
||||
break;
|
||||
case STATE_IMPLDECL:
|
||||
_implDecls += token;
|
||||
break;
|
||||
case STATE_HDRDECL:
|
||||
_headerDecls += token;
|
||||
break;
|
||||
case STATE_BLOCK:
|
||||
handlerStream << token;
|
||||
break;
|
||||
case STATE_EXPR:
|
||||
handlerStream << token;
|
||||
break;
|
||||
case STATE_COMMENT:
|
||||
break;
|
||||
case STATE_ATTR:
|
||||
_attrs += token;
|
||||
break;
|
||||
}
|
||||
}
|
||||
nextToken(pageStream, token);
|
||||
}
|
||||
|
||||
if (state == STATE_MARKUP)
|
||||
{
|
||||
handlerStream << MARKUP_END;
|
||||
}
|
||||
else throw Poco::SyntaxException("unclosed meta or code block", where());
|
||||
}
|
||||
|
||||
|
||||
void Page::parseAttributes(std::ostream& handlerStream)
|
||||
{
|
||||
static const int eof = std::char_traits<char>::eof();
|
||||
|
||||
std::string basename;
|
||||
std::istringstream istr(_attrs);
|
||||
int ch = istr.get();
|
||||
while (ch != eof && std::isspace(ch)) ch = istr.get();
|
||||
while (ch != eof && std::isalnum(ch)) { basename += (char) ch; ch = istr.get(); }
|
||||
while (ch != eof && std::isspace(ch)) ch = istr.get();
|
||||
while (ch != eof)
|
||||
{
|
||||
std::string name(basename + ".");
|
||||
std::string value;
|
||||
while (ch != eof && std::isalnum(ch)) { name += (char) ch; ch = istr.get(); }
|
||||
while (ch != eof && std::isspace(ch)) ch = istr.get();
|
||||
if (ch != '=') throw Poco::SyntaxException("bad attribute syntax: '=' expected", where());
|
||||
ch = istr.get();
|
||||
while (ch != eof && std::isspace(ch)) ch = istr.get();
|
||||
if (ch != '"') throw Poco::SyntaxException("bad attribute syntax: '\"' expected", where());
|
||||
ch = istr.get();
|
||||
while (ch != eof && ch != '"') { value += (char) ch; ch = istr.get(); }
|
||||
if (ch != '"') throw Poco::SyntaxException("bad attribute syntax: '\"' expected", where());
|
||||
ch = istr.get();
|
||||
handleAttribute(name, value, handlerStream);
|
||||
while (ch != eof && std::isspace(ch)) ch = istr.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Page::nextToken(std::istream& istr, std::string& token)
|
||||
{
|
||||
token.clear();
|
||||
int ch = istr.get();
|
||||
if (ch != -1)
|
||||
{
|
||||
if (ch == '<' && istr.peek() == '%')
|
||||
{
|
||||
token += "<%";
|
||||
ch = istr.get();
|
||||
ch = istr.peek();
|
||||
switch (ch)
|
||||
{
|
||||
case '!':
|
||||
ch = istr.get();
|
||||
token += (char) ch;
|
||||
if (istr.peek() == '!')
|
||||
{
|
||||
ch = istr.get();
|
||||
token += (char) ch;
|
||||
}
|
||||
break;
|
||||
case '=':
|
||||
ch = istr.get();
|
||||
token += (char) ch;
|
||||
break;
|
||||
case '@':
|
||||
ch = istr.get();
|
||||
token += (char) ch;
|
||||
break;
|
||||
case '-':
|
||||
ch = istr.get();
|
||||
token += (char) ch;
|
||||
if (istr.peek() == '-')
|
||||
{
|
||||
ch = istr.get();
|
||||
token += (char) ch;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (ch == '%' && istr.peek() == '>')
|
||||
{
|
||||
token += "%>";
|
||||
ch = istr.get();
|
||||
}
|
||||
else token += (char) ch;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Page::handleAttribute(const std::string& name, const std::string& value, std::ostream& handlerStream)
|
||||
{
|
||||
if (name == "include.page")
|
||||
{
|
||||
include(value, handlerStream);
|
||||
}
|
||||
else
|
||||
{
|
||||
set(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Page::include(const std::string& path, std::ostream& handlerStream)
|
||||
{
|
||||
Poco::Path currentPath(_paths.back());
|
||||
Poco::Path includePath(path);
|
||||
currentPath.resolve(includePath);
|
||||
handlerStream << "\t// begin include " << currentPath.toString() << "\n";
|
||||
_paths.push_back(currentPath.toString());
|
||||
if (_paths.size() > 100) throw Poco::ApplicationException("Too many includes", where());
|
||||
Poco::FileInputStream includeStream(currentPath.toString());
|
||||
parse(includeStream, handlerStream);
|
||||
_paths.pop_back();
|
||||
handlerStream << "\t// end include " << currentPath.toString() << "\n";
|
||||
}
|
||||
|
||||
|
||||
std::string Page::where()
|
||||
{
|
||||
std::string result("in file '");
|
||||
std::vector<std::string>::reverse_iterator it = _paths.rbegin();
|
||||
result += *it;
|
||||
result += "'";
|
||||
++it;
|
||||
while (it != _paths.rend())
|
||||
{
|
||||
result += "\n\tincluded from file ";
|
||||
result += "'";
|
||||
result += *it;
|
||||
result += "'";
|
||||
++it;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
//
|
||||
// Page.h
|
||||
//
|
||||
// $Id: //poco/Main/PageCompiler/src/Page.h#1 $
|
||||
// $Id: //poco/Main/PageCompiler/src/Page.h#2 $
|
||||
//
|
||||
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
||||
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
|
@ -35,9 +35,7 @@
|
|||
|
||||
|
||||
#include "Poco/Net/NameValueCollection.h"
|
||||
#include <vector>
|
||||
#include <istream>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
class Page: public Poco::Net::NameValueCollection
|
||||
|
@ -45,76 +43,74 @@ class Page: public Poco::Net::NameValueCollection
|
|||
/// handler code and declarations, as well as page attributes.
|
||||
{
|
||||
public:
|
||||
Page(const std::string& basePath);
|
||||
Page();
|
||||
/// Creates a Page.
|
||||
|
||||
~Page();
|
||||
/// Destroys the Page.
|
||||
|
||||
const std::string& headerDecls() const;
|
||||
std::stringstream& headerDecls();
|
||||
/// Returns the user-specified declarations for the header file.
|
||||
|
||||
const std::string& implDecls() const;
|
||||
const std::stringstream& headerDecls() const;
|
||||
/// Returns the user-specified declarations for the header file.
|
||||
|
||||
std::stringstream& implDecls();
|
||||
/// Returns the user-specified declarations for the source file.
|
||||
|
||||
const std::string& handler() const;
|
||||
const std::stringstream& implDecls() const;
|
||||
/// Returns the user-specified declarations for the source file.
|
||||
|
||||
std::stringstream& handler();
|
||||
/// Returns the request handler code.
|
||||
|
||||
void parse(std::istream& istr);
|
||||
/// Parses a HTML file containing server page directives.
|
||||
|
||||
protected:
|
||||
enum ParsingState
|
||||
{
|
||||
STATE_MARKUP,
|
||||
STATE_IMPLDECL,
|
||||
STATE_HDRDECL,
|
||||
STATE_BLOCK,
|
||||
STATE_EXPR,
|
||||
STATE_COMMENT,
|
||||
STATE_ATTR
|
||||
};
|
||||
|
||||
virtual void handleAttribute(const std::string& name, const std::string& value, std::ostream& handlerStream);
|
||||
void include(const std::string& path, std::ostream& handlerStream);
|
||||
void parse(std::istream& pageStream, std::ostream& handlerStream);
|
||||
void addHeaderDecls(const std::string& decls);
|
||||
void addImplDecls(const std::string& decls);
|
||||
void addAttrs(const std::string& attrs);
|
||||
void parseAttributes(std::ostream& handlerStream);
|
||||
void nextToken(std::istream& istr, std::string& token);
|
||||
std::string where();
|
||||
|
||||
static const std::string MARKUP_BEGIN;
|
||||
static const std::string MARKUP_END;
|
||||
static const std::string EXPR_BEGIN;
|
||||
static const std::string EXPR_END;
|
||||
|
||||
const std::stringstream& handler() const;
|
||||
/// Returns the request handler code.
|
||||
|
||||
private:
|
||||
std::string _headerDecls;
|
||||
std::string _implDecls;
|
||||
std::string _handler;
|
||||
std::string _attrs;
|
||||
std::vector<std::string> _paths;
|
||||
Page(const Page&);
|
||||
Page& operator = (const Page&);
|
||||
|
||||
std::stringstream _headerDecls;
|
||||
std::stringstream _implDecls;
|
||||
std::stringstream _handler;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// inlines
|
||||
//
|
||||
inline const std::string& Page::headerDecls() const
|
||||
inline std::stringstream& Page::headerDecls()
|
||||
{
|
||||
return _headerDecls;
|
||||
}
|
||||
|
||||
|
||||
inline const std::string& Page::implDecls() const
|
||||
inline const std::stringstream& Page::headerDecls() const
|
||||
{
|
||||
return _headerDecls;
|
||||
}
|
||||
|
||||
|
||||
inline std::stringstream& Page::implDecls()
|
||||
{
|
||||
return _implDecls;
|
||||
}
|
||||
|
||||
|
||||
inline const std::string& Page::handler() const
|
||||
inline const std::stringstream& Page::implDecls() const
|
||||
{
|
||||
return _implDecls;
|
||||
}
|
||||
|
||||
|
||||
inline std::stringstream& Page::handler()
|
||||
{
|
||||
return _handler;
|
||||
}
|
||||
|
||||
|
||||
inline const std::stringstream& Page::handler() const
|
||||
{
|
||||
return _handler;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
//
|
||||
// PageCompiler.cpp
|
||||
//
|
||||
// $Id: //poco/Main/PageCompiler/src/PageCompiler.cpp#1 $
|
||||
// $Id: //poco/Main/PageCompiler/src/PageCompiler.cpp#2 $
|
||||
//
|
||||
// A compiler that compiler HTML pages containing JSP directives into C++ classes.
|
||||
//
|
||||
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
|
||||
// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
|
@ -46,9 +46,14 @@
|
|||
#include "Poco/StringTokenizer.h"
|
||||
#include "Poco/LineEndingConverter.h"
|
||||
#include "Page.h"
|
||||
#include "PageReader.h"
|
||||
#include "CodeWriter.h"
|
||||
#include "ApacheCodeWriter.h"
|
||||
#include "OSPCodeWriter.h"
|
||||
#include <cctype>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
|
||||
using Poco::Util::Application;
|
||||
|
@ -187,10 +192,11 @@ protected:
|
|||
|
||||
void compile(const std::string& path)
|
||||
{
|
||||
Page page(path);
|
||||
Page page;
|
||||
|
||||
FileInputStream srcStream(path);
|
||||
page.parse(srcStream);
|
||||
PageReader pageReader(page, path);
|
||||
pageReader.parse(srcStream);
|
||||
|
||||
Path p(path);
|
||||
config().setString("inputFileName", p.getFileName());
|
||||
|
@ -211,6 +217,8 @@ protected:
|
|||
clazz[0] = std::toupper(clazz[0]);
|
||||
}
|
||||
|
||||
std::auto_ptr<CodeWriter> pCodeWriter(createCodeWriter(page, clazz));
|
||||
|
||||
p.setExtension("h");
|
||||
std::string headerPath = p.toString();
|
||||
std::string headerFileName = p.getFileName();
|
||||
|
@ -218,7 +226,8 @@ protected:
|
|||
config().setString("outputFilePath", headerPath);
|
||||
FileOutputStream headerStream(headerPath);
|
||||
OutputLineEndingConverter headerLEC(headerStream);
|
||||
writeHeader(headerLEC, page, clazz, p.getFileName());
|
||||
writeFileHeader(headerLEC);
|
||||
pCodeWriter->writeHeader(headerLEC, p.getFileName());
|
||||
|
||||
p.setExtension("cpp");
|
||||
std::string implPath = p.toString();
|
||||
|
@ -226,10 +235,11 @@ protected:
|
|||
config().setString("outputFilePath", implPath);
|
||||
FileOutputStream implStream(implPath);
|
||||
OutputLineEndingConverter implLEC(implStream);
|
||||
writeImpl(implLEC, page, clazz, headerFileName);
|
||||
writeFileHeader(implLEC);
|
||||
pCodeWriter->writeImpl(implLEC, headerFileName);
|
||||
}
|
||||
|
||||
void writeHeader(std::ostream& ostr, Page& page, const std::string& clazz, const std::string& headerFileName)
|
||||
void writeFileHeader(std::ostream& ostr)
|
||||
{
|
||||
std::string fileHeader = config().getString("PageCompiler.fileHeader", "");
|
||||
if (!fileHeader.empty())
|
||||
|
@ -237,272 +247,16 @@ protected:
|
|||
ostr << fileHeader << std::endl;
|
||||
ostr << "\n\n";
|
||||
}
|
||||
Path p(headerFileName);
|
||||
std::string guard(p.getBaseName());
|
||||
guard += "_INCLUDED";
|
||||
ostr << "#ifndef " << guard << "\n";
|
||||
ostr << "#define " << guard << "\n";
|
||||
ostr << "\n\n";
|
||||
ostr << "#include \"Poco/Net/HTTPRequestHandler.h\"\n";
|
||||
}
|
||||
|
||||
CodeWriter* createCodeWriter(const Page& page, const std::string& clazz)
|
||||
{
|
||||
if (_generateOSPCode)
|
||||
{
|
||||
ostr << "#include \"Poco/OSP/Web/WebRequestHandlerFactory.h\"\n";
|
||||
ostr << "#include \"Poco/OSP/BundleContext.h\"\n";
|
||||
}
|
||||
return new OSPCodeWriter(page, clazz);
|
||||
else if (_generateApacheCode)
|
||||
{
|
||||
ostr << "#include \"Poco/Net/HTTPRequestHandlerFactory.h\"\n";
|
||||
}
|
||||
|
||||
ostr << "\n\n";
|
||||
|
||||
const std::string& decls = page.headerDecls();
|
||||
if (!decls.empty())
|
||||
{
|
||||
ostr << decls;
|
||||
ostr << "\n\n";
|
||||
}
|
||||
|
||||
beginNamespace(ostr, page);
|
||||
|
||||
std::string base(page.get("page.baseClass", "Poco::Net::HTTPRequestHandler"));
|
||||
std::string ctorArg;
|
||||
if (_generateOSPCode)
|
||||
ctorArg = "Poco::OSP::BundleContext::Ptr";
|
||||
return new ApacheCodeWriter(page, clazz);
|
||||
else
|
||||
ctorArg = page.get("page.ctorArg", "");
|
||||
|
||||
std::string exprt(page.get("page.export", ""));
|
||||
if (!exprt.empty()) exprt += ' ';
|
||||
|
||||
ostr << "class " << exprt << clazz << ": public " << base << "\n";
|
||||
ostr << "{\n";
|
||||
ostr << "public:\n";
|
||||
if (!ctorArg.empty())
|
||||
{
|
||||
ostr << "\t" << clazz << "(" << ctorArg << ");\n";
|
||||
ostr << "\n";
|
||||
}
|
||||
ostr << "\tvoid handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response);\n";
|
||||
|
||||
if (_generateOSPCode)
|
||||
writeOSPHeader(ostr);
|
||||
|
||||
ostr << "};\n";
|
||||
|
||||
if (_generateOSPCode)
|
||||
{
|
||||
ostr << "\n\n";
|
||||
writeFactoryHeader(ostr, page, clazz, "Poco::OSP::Web::WebRequestHandlerFactory");
|
||||
}
|
||||
else if (_generateApacheCode)
|
||||
{
|
||||
ostr << "\n\n";
|
||||
writeFactoryHeader(ostr, page, clazz, "Poco::Net::HTTPRequestHandlerFactory");
|
||||
}
|
||||
|
||||
endNamespace(ostr, page);
|
||||
|
||||
ostr << "\n\n";
|
||||
ostr << "#endif // " << guard << "\n";
|
||||
}
|
||||
|
||||
void writeImpl(std::ostream& ostr, Page& page, const std::string& clazz, const std::string& headerFileName)
|
||||
{
|
||||
std::string fileHeader = config().getString("PageCompiler.fileHeader", "");
|
||||
if (!fileHeader.empty())
|
||||
{
|
||||
ostr << fileHeader << std::endl;
|
||||
ostr << "\n\n";
|
||||
}
|
||||
ostr << "#include \"" << headerFileName << "\"\n";
|
||||
ostr << "#include \"Poco/Net/HTTPServerRequest.h\"\n";
|
||||
ostr << "#include \"Poco/Net/HTTPServerResponse.h\"\n";
|
||||
ostr << "#include \"Poco/Net/HTMLForm.h\"\n";
|
||||
|
||||
if (_generateOSPCode)
|
||||
{
|
||||
if (page.has("page.session"))
|
||||
{
|
||||
ostr << "#include \"Poco/OSP/Web/WebSession.h\"\n";
|
||||
ostr << "#include \"Poco/OSP/Web/WebSessionManager.h\"\n";
|
||||
ostr << "#include \"Poco/OSP/ServiceRegistry.h\"\n";
|
||||
}
|
||||
}
|
||||
else if (_generateApacheCode)
|
||||
{
|
||||
ostr << "#include \"Poco/ClassLibrary.h\"\n";
|
||||
}
|
||||
|
||||
ostr << "\n\n";
|
||||
|
||||
const std::string& decls = page.implDecls();
|
||||
if (!decls.empty())
|
||||
{
|
||||
ostr << decls;
|
||||
ostr << "\n\n";
|
||||
}
|
||||
|
||||
beginNamespace(ostr, page);
|
||||
|
||||
Path p(headerFileName);
|
||||
std::string base(page.get("page.baseClass", "Poco::Net::HTTPRequestHandler"));
|
||||
std::string ctorArg(page.get("page.ctorArg", ""));
|
||||
|
||||
if (_generateOSPCode)
|
||||
{
|
||||
ostr << clazz << "::" << clazz << "(Poco::OSP::BundleContext::Ptr pContext):\n";
|
||||
ostr << "\t_pContext(pContext)\n";
|
||||
ostr << "{\n}\n";
|
||||
ostr << "\n\n";
|
||||
}
|
||||
else if (!ctorArg.empty())
|
||||
{
|
||||
ostr << clazz << "::" << clazz << "(" << ctorArg << " arg):\n";
|
||||
ostr << "\t" << base << "(arg)\n";
|
||||
ostr << "{\n}\n";
|
||||
ostr << "\n\n";
|
||||
}
|
||||
|
||||
ostr << "void " << clazz << "::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response)\n";
|
||||
ostr << "{\n";
|
||||
|
||||
if (_generateOSPCode && page.has("page.session"))
|
||||
{
|
||||
writeOSPSession(ostr, page);
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
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 << page.handler();
|
||||
|
||||
ostr << "}\n";
|
||||
|
||||
if (_generateOSPCode)
|
||||
{
|
||||
ostr << "\n\n";
|
||||
writeFactoryImpl(ostr, page, clazz, "context()");
|
||||
}
|
||||
else if (_generateApacheCode)
|
||||
{
|
||||
ostr << "\n\n";
|
||||
writeFactoryImpl(ostr, page, clazz, "");
|
||||
}
|
||||
|
||||
endNamespace(ostr, page);
|
||||
|
||||
if (_generateApacheCode)
|
||||
writeManifest(ostr, page, clazz);
|
||||
}
|
||||
|
||||
void beginNamespace(std::ostream& ostr, Page& page)
|
||||
{
|
||||
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 endNamespace(std::ostream& ostr, Page& page)
|
||||
{
|
||||
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 writeOSPSession(std::ostream& ostr, Page& page)
|
||||
{
|
||||
ostr << "\tPoco::OSP::Web::WebSession::Ptr session;\n";
|
||||
ostr << "\t{\n";
|
||||
ostr << "\t\tPoco::OSP::ServiceRef::Ptr pWebSessionManagerRef = context()->registry().findByName(Poco::OSP::Web::WebSessionManager::SERVICE_NAME);\n";
|
||||
ostr << "\t\tif (pWebSessionManagerRef)\n";
|
||||
ostr << "\t\t{\n";
|
||||
ostr << "\t\t\tPoco::OSP::Web::WebSessionManager::Ptr pWebSessionManager = pWebSessionManagerRef->castedInstance<Poco::OSP::Web::WebSessionManager>();\n";
|
||||
ostr << "\t\t\tsession = pWebSessionManager->find(\"" << page.get("page.session") << "\", request);\n";
|
||||
ostr << "\t\t\tif (session.isNull())\n";
|
||||
ostr << "\t\t\t\tsession = pWebSessionManager->get(\"" << page.get("page.session") << "\", request, " << page.get("page.sessionTimeout", "30") << ", context());\n";
|
||||
ostr << "\t\t}\n";
|
||||
ostr << "\t}\n";
|
||||
}
|
||||
|
||||
void writeOSPHeader(std::ostream& ostr)
|
||||
{
|
||||
ostr << "\n";
|
||||
ostr << "protected:\n";
|
||||
ostr << "\tPoco::OSP::BundleContext::Ptr context() const\n";
|
||||
ostr << "\t{\n";
|
||||
ostr << "\t\treturn _pContext;\n";
|
||||
ostr << "\t}\n";
|
||||
ostr << "\n";
|
||||
ostr << "private:\n";
|
||||
ostr << "\tPoco::OSP::BundleContext::Ptr _pContext;\n";
|
||||
}
|
||||
|
||||
void writeFactoryHeader(std::ostream& ostr, Page& page, const std::string& clazz, const std::string& base)
|
||||
{
|
||||
ostr << "class " << clazz << "Factory: public " << base << "\n";
|
||||
ostr << "{\n";
|
||||
ostr << "public:\n";
|
||||
ostr << "\tPoco::Net::HTTPRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request);\n";
|
||||
ostr << "};\n";
|
||||
}
|
||||
|
||||
void writeFactoryImpl(std::ostream& ostr, Page& page, const std::string& clazz, const std::string& arg)
|
||||
{
|
||||
ostr << "Poco::Net::HTTPRequestHandler* " << clazz << "Factory::createRequestHandler(const Poco::Net::HTTPServerRequest& request)\n";
|
||||
ostr << "{\n";
|
||||
ostr << "\treturn new " << clazz << "(" << arg << ");\n";
|
||||
ostr << "}\n";
|
||||
}
|
||||
|
||||
void writeManifest(std::ostream& ostr, Page& page, const std::string& clazz)
|
||||
{
|
||||
std::string ns = page.get("page.namespace", "");
|
||||
if (!ns.empty()) ns += "::";
|
||||
ostr << "\n\n";
|
||||
ostr << "POCO_BEGIN_MANIFEST(Poco::Net::HTTPRequestHandlerFactory)\n";
|
||||
ostr << "\tPOCO_EXPORT_CLASS(" << ns << clazz << "Factory)\n";
|
||||
ostr << "POCO_END_MANIFEST\n";
|
||||
return new CodeWriter(page, clazz);
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -0,0 +1,338 @@
|
|||
//
|
||||
// PageReader.cpp
|
||||
//
|
||||
// $Id: //poco/Main/PageCompiler/src/PageReader.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 "PageReader.h"
|
||||
#include "Page.h"
|
||||
#include "Poco/FileStream.h"
|
||||
#include "Poco/CountingStream.h"
|
||||
#include "Poco/Path.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include <cctype>
|
||||
|
||||
|
||||
const std::string PageReader::MARKUP_BEGIN("\tostr << \"");
|
||||
const std::string PageReader::MARKUP_END("\";\n");
|
||||
const std::string PageReader::EXPR_BEGIN("\tostr << ");
|
||||
const std::string PageReader::EXPR_END(";\n");
|
||||
|
||||
|
||||
PageReader::PageReader(Page& page, const std::string& path):
|
||||
_page(page),
|
||||
_pParent(0),
|
||||
_path(path),
|
||||
_line(0)
|
||||
{
|
||||
_attrs.reserve(4096);
|
||||
}
|
||||
|
||||
|
||||
PageReader::PageReader(const PageReader& parent, const std::string& path):
|
||||
_page(parent._page),
|
||||
_pParent(&parent),
|
||||
_path(path),
|
||||
_line(0)
|
||||
{
|
||||
_attrs.reserve(4096);
|
||||
}
|
||||
|
||||
|
||||
PageReader::~PageReader()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void PageReader::parse(std::istream& pageStream)
|
||||
{
|
||||
ParsingState state = STATE_MARKUP;
|
||||
|
||||
_page.handler() << MARKUP_BEGIN;
|
||||
|
||||
Poco::CountingInputStream countingPageStream(pageStream);
|
||||
std::string token;
|
||||
nextToken(countingPageStream, token);
|
||||
while (!token.empty())
|
||||
{
|
||||
_line = countingPageStream.getCurrentLineNumber();
|
||||
if (token == "<%")
|
||||
{
|
||||
if (state == STATE_MARKUP)
|
||||
{
|
||||
_page.handler() << MARKUP_END;
|
||||
state = STATE_BLOCK;
|
||||
}
|
||||
else _page.handler() << token;
|
||||
}
|
||||
else if (token == "<%!")
|
||||
{
|
||||
if (state == STATE_MARKUP)
|
||||
{
|
||||
_page.handler() << MARKUP_END;
|
||||
state = STATE_IMPLDECL;
|
||||
}
|
||||
else _page.handler() << token;
|
||||
}
|
||||
else if (token == "<%!!")
|
||||
{
|
||||
if (state == STATE_MARKUP)
|
||||
{
|
||||
_page.handler() << MARKUP_END;
|
||||
state = STATE_HDRDECL;
|
||||
}
|
||||
else _page.handler() << token;
|
||||
}
|
||||
else if (token == "<%--")
|
||||
{
|
||||
if (state == STATE_MARKUP)
|
||||
{
|
||||
_page.handler() << MARKUP_END;
|
||||
state = STATE_COMMENT;
|
||||
}
|
||||
else _page.handler() << token;
|
||||
}
|
||||
else if (token == "<%@")
|
||||
{
|
||||
if (state == STATE_MARKUP)
|
||||
{
|
||||
_page.handler() << MARKUP_END;
|
||||
state = STATE_ATTR;
|
||||
_attrs.clear();
|
||||
}
|
||||
else _page.handler() << token;
|
||||
}
|
||||
else if (token == "<%=")
|
||||
{
|
||||
if (state == STATE_MARKUP)
|
||||
{
|
||||
_page.handler() << MARKUP_END;
|
||||
_page.handler() << EXPR_BEGIN;
|
||||
state = STATE_EXPR;
|
||||
}
|
||||
else _page.handler() << token;
|
||||
}
|
||||
else if (token == "%>")
|
||||
{
|
||||
if (state == STATE_EXPR)
|
||||
{
|
||||
_page.handler() << EXPR_END;
|
||||
_page.handler() << MARKUP_BEGIN;
|
||||
state = STATE_MARKUP;
|
||||
}
|
||||
else if (state == STATE_ATTR)
|
||||
{
|
||||
parseAttributes();
|
||||
_attrs.clear();
|
||||
_page.handler() << MARKUP_BEGIN;
|
||||
state = STATE_MARKUP;
|
||||
}
|
||||
else if (state != STATE_MARKUP)
|
||||
{
|
||||
_page.handler() << MARKUP_BEGIN;
|
||||
state = STATE_MARKUP;
|
||||
}
|
||||
else _page.handler() << token;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case STATE_MARKUP:
|
||||
if (token == "\n")
|
||||
{
|
||||
_page.handler() << "\\n";
|
||||
_page.handler() << MARKUP_END;
|
||||
_page.handler() << MARKUP_BEGIN;
|
||||
}
|
||||
else if (token == "\t")
|
||||
{
|
||||
_page.handler() << "\\t";
|
||||
}
|
||||
else if (token == "\"")
|
||||
{
|
||||
_page.handler() << "\\\"";
|
||||
}
|
||||
else if (token != "\r")
|
||||
{
|
||||
_page.handler() << token;
|
||||
}
|
||||
break;
|
||||
case STATE_IMPLDECL:
|
||||
_page.implDecls() << token;
|
||||
break;
|
||||
case STATE_HDRDECL:
|
||||
_page.headerDecls() << token;
|
||||
break;
|
||||
case STATE_BLOCK:
|
||||
_page.handler() << token;
|
||||
break;
|
||||
case STATE_EXPR:
|
||||
_page.handler() << token;
|
||||
break;
|
||||
case STATE_COMMENT:
|
||||
break;
|
||||
case STATE_ATTR:
|
||||
_attrs += token;
|
||||
break;
|
||||
}
|
||||
}
|
||||
nextToken(countingPageStream, token);
|
||||
}
|
||||
|
||||
if (state == STATE_MARKUP)
|
||||
{
|
||||
_page.handler() << MARKUP_END;
|
||||
}
|
||||
else throw Poco::SyntaxException("unclosed meta or code block", where());
|
||||
}
|
||||
|
||||
|
||||
void PageReader::parseAttributes()
|
||||
{
|
||||
static const int eof = std::char_traits<char>::eof();
|
||||
|
||||
std::string basename;
|
||||
std::istringstream istr(_attrs);
|
||||
int ch = istr.get();
|
||||
while (ch != eof && std::isspace(ch)) ch = istr.get();
|
||||
while (ch != eof && std::isalnum(ch)) { basename += (char) ch; ch = istr.get(); }
|
||||
while (ch != eof && std::isspace(ch)) ch = istr.get();
|
||||
while (ch != eof)
|
||||
{
|
||||
std::string name(basename + ".");
|
||||
std::string value;
|
||||
while (ch != eof && std::isalnum(ch)) { name += (char) ch; ch = istr.get(); }
|
||||
while (ch != eof && std::isspace(ch)) ch = istr.get();
|
||||
if (ch != '=') throw Poco::SyntaxException("bad attribute syntax: '=' expected", where());
|
||||
ch = istr.get();
|
||||
while (ch != eof && std::isspace(ch)) ch = istr.get();
|
||||
if (ch != '"') throw Poco::SyntaxException("bad attribute syntax: '\"' expected", where());
|
||||
ch = istr.get();
|
||||
while (ch != eof && ch != '"') { value += (char) ch; ch = istr.get(); }
|
||||
if (ch != '"') throw Poco::SyntaxException("bad attribute syntax: '\"' expected", where());
|
||||
ch = istr.get();
|
||||
handleAttribute(name, value);
|
||||
while (ch != eof && std::isspace(ch)) ch = istr.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PageReader::nextToken(std::istream& istr, std::string& token)
|
||||
{
|
||||
token.clear();
|
||||
int ch = istr.get();
|
||||
if (ch != -1)
|
||||
{
|
||||
if (ch == '<' && istr.peek() == '%')
|
||||
{
|
||||
token += "<%";
|
||||
ch = istr.get();
|
||||
ch = istr.peek();
|
||||
switch (ch)
|
||||
{
|
||||
case '!':
|
||||
ch = istr.get();
|
||||
token += (char) ch;
|
||||
if (istr.peek() == '!')
|
||||
{
|
||||
ch = istr.get();
|
||||
token += (char) ch;
|
||||
}
|
||||
break;
|
||||
case '=':
|
||||
ch = istr.get();
|
||||
token += (char) ch;
|
||||
break;
|
||||
case '@':
|
||||
ch = istr.get();
|
||||
token += (char) ch;
|
||||
break;
|
||||
case '-':
|
||||
ch = istr.get();
|
||||
token += (char) ch;
|
||||
if (istr.peek() == '-')
|
||||
{
|
||||
ch = istr.get();
|
||||
token += (char) ch;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (ch == '%' && istr.peek() == '>')
|
||||
{
|
||||
token += "%>";
|
||||
ch = istr.get();
|
||||
}
|
||||
else token += (char) ch;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PageReader::handleAttribute(const std::string& name, const std::string& value)
|
||||
{
|
||||
if (name == "include.page")
|
||||
{
|
||||
include(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
_page.set(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PageReader::include(const std::string& path)
|
||||
{
|
||||
Poco::Path currentPath(_path);
|
||||
Poco::Path includePath(path);
|
||||
currentPath.resolve(includePath);
|
||||
|
||||
_page.handler() << "\t// begin include " << currentPath.toString() << "\n";
|
||||
|
||||
Poco::FileInputStream includeStream(currentPath.toString());
|
||||
PageReader includeReader(*this, currentPath.toString());
|
||||
includeReader.parse(includeStream);
|
||||
|
||||
_page.handler() << "\t// end include " << currentPath.toString() << "\n";
|
||||
}
|
||||
|
||||
|
||||
std::string PageReader::where() const
|
||||
{
|
||||
std::stringstream result;
|
||||
result << "in file '" << _path << "', line " << _line;
|
||||
const PageReader* pParent = _pParent;
|
||||
while (pParent)
|
||||
{
|
||||
result << "\n\tincluded from file '"<< pParent->_path << "', line " << pParent->_line;
|
||||
pParent = pParent->_pParent;
|
||||
}
|
||||
return result.str();
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
//
|
||||
// PageReader.h
|
||||
//
|
||||
// $Id: //poco/Main/PageCompiler/src/PageReader.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 PageReader_INCLUDED
|
||||
#define PageReader_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Poco.h"
|
||||
#include <istream>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
class Page;
|
||||
|
||||
|
||||
class PageReader
|
||||
/// This class implements the parser for reading page files
|
||||
/// containing JSP-style tags.
|
||||
{
|
||||
public:
|
||||
PageReader(Page& page, const std::string& path);
|
||||
/// Creates the PageReader, using the given Page.
|
||||
|
||||
PageReader(const PageReader& parent, const std::string& path);
|
||||
/// Creates the PageReader, using the given PageReader as parent.
|
||||
|
||||
~PageReader();
|
||||
/// Destroys the PageReader.
|
||||
|
||||
void parse(std::istream& pageStream);
|
||||
/// Parses a HTML file containing server page directives,
|
||||
/// converts the file into C++ code and adds the code
|
||||
/// to the reader's Page object. Also parses page
|
||||
/// attributes and include directives.
|
||||
|
||||
protected:
|
||||
enum ParsingState
|
||||
{
|
||||
STATE_MARKUP,
|
||||
STATE_IMPLDECL,
|
||||
STATE_HDRDECL,
|
||||
STATE_BLOCK,
|
||||
STATE_EXPR,
|
||||
STATE_COMMENT,
|
||||
STATE_ATTR
|
||||
};
|
||||
|
||||
static const std::string MARKUP_BEGIN;
|
||||
static const std::string MARKUP_END;
|
||||
static const std::string EXPR_BEGIN;
|
||||
static const std::string EXPR_END;
|
||||
|
||||
void include(const std::string& path);
|
||||
void parseAttributes();
|
||||
void nextToken(std::istream& istr, std::string& token);
|
||||
void handleAttribute(const std::string& name, const std::string& value);
|
||||
std::string where() const;
|
||||
|
||||
private:
|
||||
PageReader();
|
||||
PageReader(const PageReader&);
|
||||
PageReader& operator = (const PageReader&);
|
||||
|
||||
Page& _page;
|
||||
const PageReader* _pParent;
|
||||
std::string _path;
|
||||
std::string _attrs;
|
||||
int _line;
|
||||
};
|
||||
|
||||
|
||||
#endif // PageReader_INCLUDED
|
Загрузка…
Ссылка в новой задаче