Command handlers define the mapping of server requests to functions to execute. This chapter introduces the standard command handler.
The Wolframe standard command handler is called directmap and named so in the configuration because it only declares a redirection of the commands to functions based on the document type and the command identifier specified by the client in the request.
The declarations of the Wolframe Standard Command Handler (directmap) are specified in a program source file with the extension '.dmap' that is declared in the configuration.
The following annotated configuration example
declares (1) a program example.tdl
written in the
transaction definition language (TDL)
to contain the function declarations that can be called by
the command handler. It (2) declares the database with
name pgdb to be used as the
database for transactions. It (3) loads a description
example.dmap
that will declare the mappings
of commands to the filters used and functions called.
It (4) specifies the filter with name libxml2
to be used for documents of format XML and
(5) the filter with name cjson
to be used for documents of format JSON, if not specified
else in example.dmap
.
; Simple Data Processing Configuration Example Processor { ; Programs to load: Program example.tdl ; (1) a program with functions (in TDL) Database pgdb ; (2) references transaction database ; Command handlers to load: Cmdhandler { Directmap ; the standard command handler { Program example.dmap ; (3) description of command mappings Filter XML=libxml2 ; (4) std filter for XML document format Filter JSON=cjson ; (5) std filter for JSON document format } } }
The following source example could be one of the example.dmap
in the configuration example introduced above. It defines two commands. The first one links a command "insert" with document type
"Customer" as content to a transaction function "doInsertCustomer". The content is validated
automatically against a form named "Customer" if not explicitly defined else.
The command has no result except that it succeeds or fails. The second example command links a
command "get" with a document type "Employee" to a function "doSelectEmployee".
The input is not validated and the transaction output is validated and mapped through the
form "Employee".
COMMAND insert Customer CALL doInsertCustomer; COMMAND get Employee SKIP CALL doSelectEmployee RETURN Employee;
A command map description file like our example shown consists of instructions started with
COMMAND
and terminated by semicolon ';'. The first argument after COMMAND
is the name of the
command followed by the name of the document type of the input document. The name of the command
is optional. If not specified the first argument after COMMAND
names the input document type.
Conflicts with keywords and names are solved by using strings instead of identifiers. The standard command handler description language has the following keywords:
COMMAND |
CALL |
CONTEXT |
RETURN |
SKIP |
FILTER |
INPUT |
OUTPUT |
AUTHORIZE |
The following example shows the simplest possible declaration. It states that documents with the document type "Document" are forwarded to a function with the same name "Document".
COMMAND Document;
The next example adds a action name to the declaration. The implicit name of the function called is insertDocument:
COMMAND insert Document;
For declaring the function called explicitly like for example a function doInsertDocument
we need to declare it with CALL <functionname>
:
COMMAND insert Document CALL doInsertDocument;
The document type returned is specified with RETURN <doctype>
:
COMMAND process Document RETURN Document;
or with explicit naming of a function called
COMMAND process Document CALL doProcessDocument RETURN Document;
We can define additional document meta data or overload existing document meta or inherited document meta from input or a referenced form in the output. This is done with a comma separated list of attribute assignments in curly brackets after the document type name like:
COMMAND process Document CALL doProcessDocument RETURN Document { root = 'doc', schema = 'bla.com/schema' };
If you want to skip the input document validation, either because you are dealing
with legacy software where a strict definition of a schema is not possible or
because the function called has strict typing and validates the input on its own (.NET,C++),
then you can add a declaration SKIP
:
COMMAND process Document SKIP CALL doProcessDocument RETURN Document;
The same you can specify for the output with a SKIP
following the RETURN
of the output declaration:
COMMAND process Document CALL doProcessDocument RETURN SKIP Document;
For being able to skip validation of output of a processed XML
we have additionally to specify the root element as document
meta data. This defintion can be part of a form declaration
(not used for validation) or it can be specified after
the RETURN SKIP
and the document
type identifier in a standard command handler instruction.
The following example shows such a definition with 'list'
as root element defined. Such a command definition makes sense
for strongly typed languages like .NET or native C++ where data
validation can be delagated completely to the strongly typed
structure definition of the called function.
COMMAND process Document CALL doProcessDocument RETURN SKIP Document {root='list'};
If we want to return a document as standalone
(standalone="yes" in the header in case of XML) without validation,
we have to declare this with explicit document meta data as
RETURN SKIP {standalone='yes',root='root'}
.
COMMAND process Document CALL doProcessDocument RETURN SKIP {standalone='yes',root='list'};
For most processing it's enough to declare the standard filters in the configuration of the command handler. But in certain cases we want to declare a filter explicitly for a command, for example to preprocess a certain document type with an XSLT filter. Explicitly declared filters always refer to a document format and documents of other formats have to be converted first or they cannot be preprocessed. The conversions mechanisms we will explain in detail later. Explicit filter declarations are done with
FILTER <name>
or
FILTER INPUT <inputfiltername>
or
FILTER OUTPUT <outputfiltername>
or
FILTER INPUT <inputfiltername> OUTPUT <outputfiltername>
Here is an example:
COMMAND process Document FILTER INPUT myXsltInputFilter CALL doProcessDocument RETURN Document;
We can tag a command to be allowed only after an authorization check. The check denies command execution with an error if the login of the user does not allow the execution of the command. The call is the same as in TDL for example. Authorization checks are triggered by the AUTHORIZE attribute with one or two arguments as follows:
AUTHORIZE <authfunc>
or
AUTHORIZE <authfunc> <resource>
Wolframe functions that are written in a language other than C++ are usually pure data in / data out functions. So the input document defines the input. But sometimes we need to include data from the user context into processing, for example for inserting or editing some personal data. Wolframe gives us the possibility to include data from the execution context into the input document. We do this with the directive CONTEXT followed by a list of comma ',' separated assignments in curly brackets '{' '}'. The following example adds an element 'uname' that does not exist yet in the input to the input document before execution (after validation). The value of the add 'uname' element is the user name of the user issuing the request.
COMMAND insert UserData CONTEXT { uname = UserName } CALL doInsertUserData;
This way we keep the processing functions as pure data functions. We are in certain cases able to inject some login dependent data in a controlled way, without exposing an API to all language bindings for being able to access everything from everywhere.
For better readability you can use optional '(' ')' brackets on the arguments of the command declaration:
COMMAND ( process Document ) FILTER INPUT myXsltInputFilter CALL doProcessDocument RETURN Document;
Each command declaration has as already explained the form
COMMAND <doctype> [OPTIONS] ;
or
COMMAND <action> <doctype> [OPTIONS] ;
The following table shows an overview of the elements that can be used in the [OPTIONS]
part of the command:
Table 5.1. Options
Keywords | Arguments | Description |
---|---|---|
CALL | Function Name | Names the function to be called for processing the request |
RETURN | Document Type | Specifies the type of the document returned and forces validation of the output |
RETURN SKIP | Document Type | Specifies the type of the document returned but skips validation of the output |
SKIP | (no arguments) | Specifies the input document validation to be skipped |
FILTER INPUT | Filter Name | Specifies that the filter <Name> should be used as input filter |
FILTER OUTPUT | Filter Name | Specifies that the filter <Name> should be used as output filter |
FILTER | Filter Name | Specifies that the filter <Name> should be used both as input and output filter |
AUTHORIZE | func res | Specifies that the function <func> should be called with the resource <res> to check if the user is allowed to execute the command. |
Copyright © 2014 - Project Wolframe - All Rights Reserved