added PageCompiler

This commit is contained in:
Guenter Obiltschnig 2008-01-16 18:19:08 +00:00
parent 41c775b41d
commit fdc2e6c0eb
12 changed files with 1863 additions and 0 deletions

17
PageCompiler/Makefile Normal file
View File

@ -0,0 +1,17 @@
#
# Makefile
#
# $Id: //poco/Main/PageCompiler/Makefile#1 $
#
# Makefile for Poco C++ Server Page Compiler
#
include $(POCO_BASE)/build/rules/global
objects = Page PageCompiler
target = cpspc
target_version = 1
target_libs = PocoNet PocoUtil PocoXML PocoFoundation
include $(POCO_BASE)/build/rules/exec

View File

@ -0,0 +1,21 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PageCompiler", "PageCompiler_vs71.vcproj", "{73408DCF-2E65-47AF-BF38-7466DAB8D5CB}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
debug_shared = debug_shared
release_shared = release_shared
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{73408DCF-2E65-47AF-BF38-7466DAB8D5CB}.debug_shared.ActiveCfg = debug_shared|Win32
{73408DCF-2E65-47AF-BF38-7466DAB8D5CB}.debug_shared.Build.0 = debug_shared|Win32
{73408DCF-2E65-47AF-BF38-7466DAB8D5CB}.release_shared.ActiveCfg = release_shared|Win32
{73408DCF-2E65-47AF-BF38-7466DAB8D5CB}.release_shared.Build.0 = release_shared|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,280 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="PageCompiler"
ProjectGUID="{73408DCF-2E65-47AF-BF38-7466DAB8D5CB}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="debug_shared|Win32"
OutputDirectory="obj\debug_shared"
IntermediateDirectory="obj\debug_shared"
ConfigurationType="1"
UseOfMFC="2"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=".\include;..\Foundation\include;..\XML\include;..\Util\include;..\Net\include"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;POCO_DLL;WINVER=0x0500"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
BufferSecurityCheck="TRUE"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="PocoFoundationd.lib PocoXMLd.lib PocoUtild.lib PocoNetd.lib"
OutputFile="bin/cpspcd.exe"
LinkIncremental="2"
AdditionalLibraryDirectories="..\lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="bin/PageCompilerd.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="release_shared|Win32"
OutputDirectory="obj\release_shared"
IntermediateDirectory="obj\release_shared"
ConfigurationType="1"
UseOfMFC="2"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="4"
InlineFunctionExpansion="1"
EnableIntrinsicFunctions="TRUE"
FavorSizeOrSpeed="1"
OmitFramePointers="TRUE"
OptimizeForWindowsApplication="TRUE"
AdditionalIncludeDirectories=".\include;..\Foundation\include;..\XML\include;..\Util\include;..\Net\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;POCO_DLL;WINVER=0x0500"
StringPooling="TRUE"
RuntimeLibrary="2"
BufferSecurityCheck="FALSE"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="PocoFoundation.lib PocoXML.lib PocoUtil.lib PocoNet.lib"
OutputFile="bin/cpspc.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="..\lib"
GenerateDebugInformation="FALSE"
ProgramDatabaseFile=""
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="debug_static|Win32"
OutputDirectory="obj\debug_static"
IntermediateDirectory="obj\debug_static"
ConfigurationType="1"
UseOfMFC="2"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=".\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;POCO_STATIC;WINVER=0x0500"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
BufferSecurityCheck="TRUE"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="PocoFoundationmtd.lib PocoXMLmtd.lib PocoUtilmtd.lib advapi32.lib"
OutputFile="bin/PageCompilermtd.exe"
LinkIncremental="2"
AdditionalLibraryDirectories="..\..\..\lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="bin/PageCompilermtd.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="release_static|Win32"
OutputDirectory="obj\release_static"
IntermediateDirectory="obj\release_static"
ConfigurationType="1"
UseOfMFC="2"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="4"
InlineFunctionExpansion="1"
EnableIntrinsicFunctions="TRUE"
FavorSizeOrSpeed="1"
OmitFramePointers="TRUE"
OptimizeForWindowsApplication="TRUE"
AdditionalIncludeDirectories=".\include;..\..\..\Foundation\include;..\..\..\XML\include;..\..\..\Util\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;POCO_STATIC;WINVER=0x0500"
StringPooling="TRUE"
RuntimeLibrary="2"
BufferSecurityCheck="FALSE"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="PocoFoundationmt.lib PocoXMLmt.lib PocoUtilmt.lib advapi32.lib"
OutputFile="bin/PageCompilermt.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="..\..\..\lib"
GenerateDebugInformation="FALSE"
ProgramDatabaseFile=""
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Configuration Files"
Filter="">
<File
RelativePath=".\cpspc.properties">
</File>
</Filter>
<Filter
Name="Source Files"
Filter="">
<File
RelativePath=".\src\Page.cpp">
</File>
<File
RelativePath=".\src\PageCompiler.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="">
<File
RelativePath=".\src\Page.h">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PageCompiler", "PageCompiler_vs80.vcproj", "{E12E5C71-79A4-495A-848F-F1710111E610}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
debug_shared|Win32 = debug_shared|Win32
release_shared|Win32 = release_shared|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E12E5C71-79A4-495A-848F-F1710111E610}.debug_shared|Win32.ActiveCfg = debug_shared|Win32
{E12E5C71-79A4-495A-848F-F1710111E610}.debug_shared|Win32.Build.0 = debug_shared|Win32
{E12E5C71-79A4-495A-848F-F1710111E610}.release_shared|Win32.ActiveCfg = release_shared|Win32
{E12E5C71-79A4-495A-848F-F1710111E610}.release_shared|Win32.Build.0 = release_shared|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,229 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="PageCompiler"
ProjectGUID="{E12E5C71-79A4-495A-848F-F1710111E610}"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="debug_shared|Win32"
OutputDirectory="obj\debug_shared"
IntermediateDirectory="obj\debug_shared"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="2"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=".\include;..\Foundation\include;..\XML\include;..\Util\include;..\Net\include"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;POCO_DLL;WINVER=0x0500"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
BufferSecurityCheck="true"
TreatWChar_tAsBuiltInType="true"
ForceConformanceInForLoopScope="true"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="PocoFoundationd.lib PocoXMLd.lib PocoUtild.lib PocoNetd.lib"
OutputFile="bin/cpspcd.exe"
LinkIncremental="2"
AdditionalLibraryDirectories="..\lib"
GenerateDebugInformation="true"
ProgramDatabaseFile="bin/cpspcd.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="release_shared|Win32"
OutputDirectory="obj\release_shared"
IntermediateDirectory="obj\release_shared"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="2"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="4"
InlineFunctionExpansion="1"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
AdditionalIncludeDirectories=".\include;..\Foundation\include;..\XML\include;..\Util\include;..\Net\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;POCO_DLL;WINVER=0x0500"
StringPooling="true"
RuntimeLibrary="2"
BufferSecurityCheck="false"
TreatWChar_tAsBuiltInType="true"
ForceConformanceInForLoopScope="true"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="PocoFoundation.lib PocoXML.lib PocoUtil.lib PocoNet.lib"
OutputFile="bin/cpspc.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="..\lib"
GenerateDebugInformation="false"
ProgramDatabaseFile=""
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Configuration Files"
>
<File
RelativePath=".\cpspc.properties"
>
</File>
</Filter>
<Filter
Name="Source Files"
>
<File
RelativePath=".\src\Page.cpp"
>
</File>
<File
RelativePath=".\src\PageCompiler.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
>
<File
RelativePath=".\src\Page.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1 @@
PageCompiler.fileHeader = //\n// ${outputFileName}\n//\n// This file has been generated from ${inputFileName} on ${dateTime}.\n//

View File

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

357
PageCompiler/src/Page.cpp Normal file
View File

@ -0,0 +1,357 @@
//
// Page.cpp
//
// $Id: //poco/Main/PageCompiler/src/Page.cpp#1 $
//
// Copyright (c) 2007, 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 "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)
{
_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;
}

123
PageCompiler/src/Page.h Normal file
View File

@ -0,0 +1,123 @@
//
// Page.h
//
// $Id: //poco/Main/PageCompiler/src/Page.h#1 $
//
// Copyright (c) 2007, 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 Page_INCLUDED
#define Page_INCLUDED
#include "Poco/Net/NameValueCollection.h"
#include <vector>
#include <istream>
#include <ostream>
class Page: public Poco::Net::NameValueCollection
/// This class represents a server page consisting of
/// handler code and declarations, as well as page attributes.
{
public:
Page(const std::string& basePath);
/// Creates a Page.
~Page();
/// Destroys the Page.
const std::string& headerDecls() const;
/// Returns the user-specified declarations for the header file.
const std::string& implDecls() const;
/// Returns the user-specified declarations for the source file.
const std::string& handler() const;
/// 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;
private:
std::string _headerDecls;
std::string _implDecls;
std::string _handler;
std::string _attrs;
std::vector<std::string> _paths;
};
//
// inlines
//
inline const std::string& Page::headerDecls() const
{
return _headerDecls;
}
inline const std::string& Page::implDecls() const
{
return _implDecls;
}
inline const std::string& Page::handler() const
{
return _handler;
}
#endif // Page_INCLUDED

View File

@ -0,0 +1,515 @@
//
// PageCompiler.cpp
//
// $Id: //poco/Main/PageCompiler/src/PageCompiler.cpp#1 $
//
// A compiler that compiler HTML pages containing JSP directives into C++ classes.
//
// Copyright (c) 2007, 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 "Poco/Util/Application.h"
#include "Poco/Util/Option.h"
#include "Poco/Util/OptionSet.h"
#include "Poco/Util/HelpFormatter.h"
#include "Poco/Util/AbstractConfiguration.h"
#include "Poco/AutoPtr.h"
#include "Poco/FileStream.h"
#include "Poco/Path.h"
#include "Poco/DateTime.h"
#include "Poco/DateTimeFormatter.h"
#include "Poco/DateTimeFormat.h"
#include "Poco/StringTokenizer.h"
#include "Poco/LineEndingConverter.h"
#include "Page.h"
#include <cctype>
#include <sstream>
#include <iostream>
using Poco::Util::Application;
using Poco::Util::Option;
using Poco::Util::OptionSet;
using Poco::Util::HelpFormatter;
using Poco::Util::AbstractConfiguration;
using Poco::Util::OptionCallback;
using Poco::AutoPtr;
using Poco::FileInputStream;
using Poco::FileOutputStream;
using Poco::Path;
using Poco::DateTime;
using Poco::DateTimeFormatter;
using Poco::DateTimeFormat;
using Poco::StringTokenizer;
using Poco::OutputLineEndingConverter;
class CompilerApp: public Application
{
public:
CompilerApp():
_helpRequested(false),
_generateOSPCode(false),
_generateApacheCode(false)
{
}
protected:
void initialize(Application& self)
{
loadConfiguration(); // load default configuration files, if present
Application::initialize(self);
}
void defineOptions(OptionSet& options)
{
Application::defineOptions(options);
options.addOption(
Option("help", "h", "display help information on command line arguments")
.required(false)
.repeatable(false)
.callback(OptionCallback<CompilerApp>(this, &CompilerApp::handleHelp)));
options.addOption(
Option("define", "D", "define a property")
.required(false)
.repeatable(true)
.argument("name=value")
.callback(OptionCallback<CompilerApp>(this, &CompilerApp::handleDefine)));
options.addOption(
Option("config-file", "f", "load configuration data from a file")
.required(false)
.repeatable(true)
.argument("file")
.callback(OptionCallback<CompilerApp>(this, &CompilerApp::handleConfig)));
options.addOption(
Option("osp", "O", "add factory class definition/implementation for use with OSP")
.required(false)
.repeatable(false)
.callback(OptionCallback<CompilerApp>(this, &CompilerApp::handleOSP)));
options.addOption(
Option("apache", "A", "add factory class definition/implementation and shared library manifest for use with ApacheConnector")
.required(false)
.repeatable(false)
.callback(OptionCallback<CompilerApp>(this, &CompilerApp::handleApache)));
}
void handleHelp(const std::string& name, const std::string& value)
{
_helpRequested = true;
displayHelp();
stopOptionsProcessing();
}
void handleDefine(const std::string& name, const std::string& value)
{
defineProperty(value);
}
void handleConfig(const std::string& name, const std::string& value)
{
loadConfiguration(value);
}
void handleOSP(const std::string& name, const std::string& value)
{
_generateOSPCode = true;
}
void handleApache(const std::string& name, const std::string& value)
{
_generateApacheCode = true;
}
void displayHelp()
{
HelpFormatter helpFormatter(options());
helpFormatter.setCommand(commandName());
helpFormatter.setUsage("OPTIONS PAGES");
helpFormatter.setHeader("The POCO C++ Server Page Compiler.");
helpFormatter.format(std::cout);
}
void defineProperty(const std::string& def)
{
std::string name;
std::string value;
std::string::size_type pos = def.find('=');
if (pos != std::string::npos)
{
name.assign(def, 0, pos);
value.assign(def, pos + 1, def.length() - pos);
}
else name = def;
config().setString(name, value);
}
int main(const std::vector<std::string>& args)
{
if (_helpRequested)
return Application::EXIT_OK;
for (std::vector<std::string>::const_iterator it = args.begin(); it != args.end(); ++it)
{
compile(*it);
}
return Application::EXIT_OK;
}
void compile(const std::string& path)
{
Page page(path);
FileInputStream srcStream(path);
page.parse(srcStream);
Path p(path);
config().setString("inputFileName", p.getFileName());
config().setString("inputFilePath", p.toString());
DateTime now;
config().setString("dateTime", DateTimeFormatter::format(now, DateTimeFormat::SORTABLE_FORMAT));
std::string clazz;
if (page.has("page.class"))
{
clazz = page.get("page.class");
p.setBaseName(clazz);
}
else
{
clazz = p.getBaseName() + "Handler";
clazz[0] = std::toupper(clazz[0]);
}
p.setExtension("h");
std::string headerPath = p.toString();
std::string headerFileName = p.getFileName();
config().setString("outputFileName", p.getFileName());
config().setString("outputFilePath", headerPath);
FileOutputStream headerStream(headerPath);
OutputLineEndingConverter headerLEC(headerStream);
writeHeader(headerLEC, page, clazz, p.getFileName());
p.setExtension("cpp");
std::string implPath = p.toString();
config().setString("outputFileName", p.getFileName());
config().setString("outputFilePath", implPath);
FileOutputStream implStream(implPath);
OutputLineEndingConverter implLEC(implStream);
writeImpl(implLEC, page, clazz, headerFileName);
}
void writeHeader(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";
}
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";
if (_generateOSPCode)
{
ostr << "#include \"Poco/OSP/Web/WebRequestHandlerFactory.h\"\n";
ostr << "#include \"Poco/OSP/BundleContext.h\"\n";
}
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";
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";
}
private:
bool _helpRequested;
bool _generateOSPCode;
bool _generateApacheCode;
};
POCO_APP_MAIN(CompilerApp)

View File

@ -0,0 +1,3 @@
<h1>This is the header</h1>
<p>Just to test the include statement</p>
<%@ foo bar="asdf"%>

View File

@ -0,0 +1,27 @@
<%@ page class="TestHandler" namespace="AI::Test" session="test"%>
<%!
#include "Poco/DateTime.h"
#include "Poco/DateTimeFormatter.h"
#include "Poco/DateTimeFormat.h"
using Poco::DateTime;
using Poco::DateTimeFormatter;
using Poco::DateTimeFormat;
%>
<%
DateTime now;
std::string dt(DateTimeFormatter::format(now, DateTimeFormat::SORTABLE_FORMAT));
%>
<html>
<head>
<title>Test Page</title>
</head>
<%-- This is a server-side comment --%>
<body>
<%@ include page="header.inc" %>
<h1>Hello, World!</h1>
<p><%= dt %></p>
</body>
</html>