(*
* <COPYRIGHT>
* Copyright 2002 Joachim Schrod Network and Publication Consultance GmbH, Gerd Stolpmann
*
* <GPL>
* This file is part of WDialog.
*
* WDialog is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* WDialog is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with WDialog; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* </>
*)
(* $Id: wd_types.mli,v 3.14 2006-03-08 00:56:45 stolpmann Exp $
* ----------------------------------------------------------------------
*
*)
(** This module defines the fundamental types for WDialog *)
type (+'a) dict = 'a Wd_dictionary.t
(** The type ['a dict] is just an abbreviation for dictionaries (mappings from
* strings to ['a]).
*)
type event =
Button of string
| Image_button of (string * int * int)
| Indexed_button of (string * string)
| Indexed_image_button of (string * string * int * int)
| No_event
| Popup_request of string (** *)
(** [ ]
*
* Events are generated when the user presses a button, clicks at a hyperlink,
* or opens a server-generated popup window.
*
* - [Button n]: The button with name [n] has been pressed
* ([<ui:button name="n" ...>])
* - [Image_button (n,x,y)]: The image button with name [n] has been pressed
* at the coordinates [(x,y)]. ([<ui:imagebutton name="n" ...>])
* - [Indexed_button (n,i)]: The button with name [n] and index [i] has been pressed
* ([<ui:button name="n" index="i" ...>])
* - [Indexed_image_button (n,i,x,y)]: The image button with name [n] and index [i]
* has been pressed at the coordinates [(x,y)].
* ([<ui:imagebutton name="n" index="i" ...>])
* - [No_event]: This value indicates that there was no event (or no
* recognized event)
* - [Popup_request s]: A server popup window has just popped up, and the contents
* for the window have been requested. The argument is the second argument
* of the "open" Javascript function that has been generated by the
* ui:server-popup element.
*)
type interactors =
{ mutable ui_buttons : string option Wd_interactor.t;
mutable ui_imagebuttons : string option Wd_interactor.t;
mutable ui_anchors : string option Wd_interactor.t;
mutable ui_indexed_buttons : string option Wd_interactor.t;
mutable ui_indexed_imagebuttons :string option Wd_interactor.t;
mutable ui_indexed_anchors : string option Wd_interactor.t;
mutable ui_vars : unit Wd_interactor.t;
mutable ui_enumvars : (string * string option * string) list;
mutable ui_uploads : unit Wd_interactor.t;
}
(** Values of this type store the mapping from the (name,index) pairs
* of interactor elements to the real CGI parameter names together
* with auxiliary components.
*
* What's the problem? Interactor elements like [ui:a] allow the programmer
* to identify these either by a single name (which is an arbitrary
* string) or by a pair of a "name" and an "index" (i.e. two arbitrary
* strings). In contrast to this, CGI parameter names are much more
* restricted. First, these names are only strings; there is no
* built-in representation for pairs of strings. Second, you cannot
* use arbitrary characters within these names because of limitations
* of the transport protocol and because of bugs in browsers. (As
* the "multipart/form-data" representation used in the transport
* protocol bases on the RFC 822 mail format, it is neither possible to
* pass 8 bit values, nor to pass control characters. A known bug
* in Netscape browsers is that the double-quote and backslash characters
* are incorrectly represented.)
*
* The solution is to generate the CGI parameter names using only
* unproblematic characters, and to keep the mapping of the original
* [string] or [string * string] to the generated CGI name. This record
* stores the mappings for the various namespaces. The mapping is
* encapsulated in the {!Wd_interactor} module, and the type
* ['a Wd_interactor.t] (where ['a] is arbitrary) represents such a mapping. The
* CGI names are simply enumerated, and the [Wd_interactor.t] value stores only
* the numbers (IDs) of the CGI parameters. The complete CGI name is formed
* using a prefix and the number stored in [Wd_interactor.t]. For example,
* ui:buttons without index have the prefix "button_"; and if the
* ui_button record component contains entries for the IDs 0, 1, and 2,
* the complete CGI names are "button_0", "button_1", and "button_2",
* respectively.
*
* The type parameter ['a] of ['a Wd_interactor.t] is the type of the
* auxiliary component stored with every entry. See below for the
* meanings in every case.
*
* The [Wd_interactor.t] structure always maps from pairs [string * string] to
* numeric IDs. Because of this, there are usually two mappings, one
* for the (name,index) pairs, and one for the simple names. The record
* components listed below that have a name with "indexed" are responsible
* for the pairs, the corresponding component without "indexed" stores
* the mapping for the simple case.
*
* The simple case is represented as [Wd_interactor.t] by using always the
* empty string [""] as index.
*
* {b THE COMPONENTS ARE:}
*
* {ol
* {- {b BUTTON-TYPE INTERACTORS:}
* {ul
* {- [ui_buttons]: Enumerates the [ui:button] interactors
* that have only a name, not an index.
* CGI prefix: "button_".
* }
* {- [ui_indexed_buttons]: Enumerates the [ui:button] interactors
* that have both a name and an index.
* CGI prefix: "xbutton_".
* }
* {- [ui_imagebuttons]: Enumerates the [ui:imagebutton] interactors
* that have only a name, not an index.
* CGI prefix: "imagebutton_".
* }
* {- [ui_indexed_imagebuttons]: Enumerates the [ui:imagebutton] interactors
* that have both a name and an index.
* CGI prefix: "ximagebutton_".
* }
* {- [ui_anchors]: Enumerates the [ui:a] interactors
* that have only a name, not an index.
* CGI prefix: "anchor_".
* }
* {- [ui_indexed_anchors]: Enumerates the [ui:a] interactors
* that have both a name and an index.
* CGI prefix: "xanchor_".
* }
* }
*
* These components use the auxiliary component to store the "goto"
* attribute of the interactor, if present.
*
* }
* {- {b BOX-LIKE INTERACTORS:}
* {ul
* {- [ui_vars]: Enumerates the interactors that are bound
* to an object variable (i.e. they have a
* [variable] attribute, like [ui:text]).
* As variables allow either only non-indexed
* names or only indexed names, this component
* contains both interactors identified by a simple
* string name and interactors identified by
* (name,index) pairs; it is not possible that
* there are conflicts between the two naming
* methods.
* CGI prefix: "var_".
* This component does not have an auxiliary
* component.
* }
* {- [ui_enumvars]: This list enumerates the simple names
* [(name, None, pg)] or pairs [(name, Some index, pg)]
* that occur in checkbox, radiobutton and select
* list interactors. [pg] is the name of the page
* where the interactor occurs (knowing the page
* is necessary for popup dialogues).
* }
* {- [ui_uploads]: Enumerates the [ui:file] interactors. These
* may only have a simple name.
* CGI prefix: "upload_".
* This component does not have an auxiliary
* component.
* }
* }
* }
* }
*)
type head = string array
(** The head of a table or matrix. The head gives every column a
* name. The names must be unique for the table/matrix.
*)
type init_expr =
[ `String_iexpr of Wd_brexpr.expr_string
| `Enum_iexpr of Wd_brexpr.expr_string list
| `Dyn_enum_iexpr of (Wd_brexpr.expr_string * Wd_brexpr.expr_string) list
| `Alist_iexpr of (Wd_brexpr.expr_string * init_expr) list
| `Matrix_iexpr of head * Wd_brexpr.expr_string array array
| `Value_iexpr of Wd_brexpr.expr
| `Map_iexpr of Wd_brexpr.expr * init_expr list
| `Dsrc_iexpr of string * Wd_brexpr.expr_string
]
(** The initializing expression for dialog variables. Such an expression
* may contain $-expressions (but not references to template parameters).
* Furthermore, it is also possible to denote arbitrary values by giving
* a $-expression (this includes functions), and to map expressions by
* applying a function.
*)
(** A table is an abstract (read-only) view on a data structure with
* certain access primitives. The table consists of several rows,
* and every row of several columns. The columns have names, defined
* in the table head.
*
* Tables may be backed by:
* - WDialog values like dynamic enumerators or matrices
* - Message catalogs
* - Arbitrary external data sources like SQL tables or results of
* SQL SELECT statements
*
* Note that "=", the equality test, checks for object identity rather
* than structural equality. See [Wd_table.compare] for a reasonable
* equality function.
*
* See [Wd_table] for table functions.
*)
class type table =
object
method head : head
(** Returns the table head *)
method select : column:string -> string -> table
(** Returns the sub table where the named [column] has the passed
* value. The returned table has the same head, i.e. the passed
* column is still present although all rows have the same value
* in it.
*)
method card : int
(** Returns the number of rows of the table. This method may be
* expensive if the rows have to be retrieved from the data source
* first before they can be counted.
*)
method iter : unit -> iterator option
(** Starts iterating the table in a certain, table-specific order.
* If the table is empty the function will return [None], otherwise
* an [iterator] is passed back. The [iterator] represents the
* current row and allows the user to get all further rows.
* Iterators must be closed (by calling [close]) when it is not
* iterated until the end of the table. This allows implementors
* of external data sources to free resources.
*
* Every invocation of [iter] starts a new query; previously
* retrieved chains of [iterator] objects are not cached.
*)
end
and iterator =
object
method row : string array
(** Returns the row this cell of the iterator chain is tied to *)
method large_row : string Stream.t array
(** Returns the same values as [row] but also supports large values.
* Every cell is represented as [string Stream.t], i.e. the value
* of the cell are the concatenated elements of the stream.
*
* If you do not have any idea what this means, just define
* {[
* method large_row = Array.map (fun s -> Stream.of_list [s]) self#row
* ]}
*)
method next : iterator option
(** Returns the next iterator cell of the chain, or [None] if this
* is the last cell. The next cell is usually computed lazily (on
* demand only), but once the cell is determined, [next] returns
* always the same object.
*)
method close : unit -> unit
(** Closes the iterator. This is only allowed for cells where [next]
* has not yet been called. After being closed, the method [next]
* returns always [None].
*)
end
type 'dlg poly_var_value =
String_value of string
| Enum_value of string list
| Dialog_value of 'dlg option
| Dyn_enum_value of (string * string) list
| Alist_value of (string * 'dlg poly_var_value) list
| Matrix_value of head * string array array
| Table_value of table
| Function_value of ('dlg ->
'dlg poly_var_value Lazy.t list -> 'dlg poly_var_value)
(** *)
(** [ ]
*
* [poly_var_value] is the type of instance variables of dialogs. There are
* nine possibilities for [poly_var_value]s:
* - [String_value s]: The instance variable contains the string [s]
* - [Enum_value [x1;x2;...]]: The instance variable contains an enumerator
* value with the internal items [x1], [x2], etc. (As variables are declared
* it is known which items are possible, and whether there are corresponding
* external values.)
* - [Dialog_value None]: The instance variable does not contain a dialog.
* - [Dialog_value (Some dlg)]: The variable contains the dialog dlg.
* - [Dyn_enum_value [(x1,y1);(x2,y2);...]]: The variable contains the enumerator
* with internal items [x1], [x2],... and the corresponding external values
* [y1], [y2], ...
* - [Alist_value [(i1,v1); (i2,v2); ...]]: The variable contains the associative
* list where the index [i1] is mapped to the value [v1], [i2] is mapped to [v2] etc.
* - [Matrix_value(h,m)]: The value is a sequence of rows, and every row is
* a sequence of the same number of columns. The matrix cells are strings.
* The columns have names as defined in [h].
* - [Table_value t]: Table values are abstract (i.e. nothing is said about the
* representation), and have only certain read-only access primitives.
* Usually a table is only a front-end to some other value or object.
* Table values cannot be marshalled and thus cannot be part of
* persistent sessions.
* - [Function_value f]: Functions can be applied for a certain dialog
* and take a list of arguments. The result is again a [poly_var_value].
* Function values cannot be marshalled and thus cannot be part of
* persistent sessions.
*
* See also {!Wd_types.var_value} below.
*)
type enum_decl =
{ enum_name : string;
mutable enum_definition : (string * string) list;
}
(** The type of an enumeration declaration (i.e. [ui:enumeration]). The component
* [enum_name] is the name of the enumeration. The component [enum_definition]
* is the list of the pairs of internal and external names, in the right order.
*)
type var_type_name =
String_type
| Enum_type of enum_decl
| Dialog_type
| Dyn_enum_type
| Matrix_type
| Table_type (** *)
(** The different variable types *)
type 'dlg poly_var_decl =
{ var_name : string;
var_type : var_type_name;
var_init : init_expr option;
var_temporary : bool;
var_associative : bool;
var_protected : bool;
}
(** This record describes variable declarations. [var_name] contains the name of the
* variable. [var_type] is the declared type according to the [type] attribute.
* [var_init] contains either [None], in which case no special initial value is
* declared, or [Some v], where [v] is the initial value. [var_temporary] corresponds
* to the [temporary] attribute, [var_associative] to the [associative] attribute,
* and finally [var_protected] to the [protected] attribute.
*)
type response_header =
{ mutable rh_status : Nethttp.http_status;
mutable rh_content_type : string;
mutable rh_cache : Netcgi.cache_control;
mutable rh_filename : string option;
mutable rh_language : string option;
mutable rh_script_type : string option;
mutable rh_style_type : string option;
mutable rh_set_cookie : Nethttp.cookie list;
mutable rh_fields : (string * string list) list;
}
(** This record contains the CGI header of the response. It is initialized
* quite early and can be modified while executing the request. The fields
* correspond to the arguments of the method [set_header] of the class
* type [cgi_activation], defined in [Netcgi_types].
*)
type debug_mode_style =
[ `Fully_encoded
| `Partially_encoded
]
(** Whether the generated HTML comments do escape HTML meta characters
* always ([`Fully_encoded]), or only partially ([`Partially_encoded]).
*)
type environment =
{ (* Overall way of operation: *)
debug_mode : bool;
debug_mode_style : debug_mode_style;
prototype_mode : bool;
server_popup_mode : bool;
(* Web variables *)
self_url : string;
response_header : response_header;
cgi : Netcgi.cgi_activation;
}
(** This record contains data that may be different for every CGI request. The
* [debug_mode] and [prototype_mode] components are true iff the corresponding
* mode is switched on. The [server_popup_mode] is true iff the current request
* is a popup request. [self_url] is the URL that invokes the CGI recursively.
* [cgi] contains the full CGI request. The [request_header] is the
* designated header of the HTTP response.
*)
type trans_vars =
{ mutable within_popup : bool;
mutable current_page : string;
mutable popup_env_initialized : bool;
mutable condition_code : bool;
(* last result of <ui:if>, <ui:ifvar>, <ui:iflang> *)
mutable serialize_session : unit -> string;
}
(** This record is private for the transformation engine. *)
type ('universe,'dialog,'environment) poly_ds_buf =
('universe,'dialog,'environment) Wd_serialize_types.poly_ds_buf =
{ ds_str : string; (* String to deserialize *)
mutable ds_pos : int; (* Current position *)
ds_end : int; (* End position *)
ds_universe : 'universe;
ds_environment : 'environment;
ds_dialogs : (int, 'dialog) Hashtbl.t;
(* maps dialog IDs to dialogs *)
}
(** The deserialization buffer *)
exception Not_found_in_catalog of string * string * string
(** Raised when a token cannot be translated. The triple is
* (dialog name, language, token).
*)
(** A message catalog maps tokens to display strings for a number of
* languages.
*)
class type message_catalog =
object
method domain : string
(** The domain name of the catalog. For catalogs defined in the scope of
* dialogs, the domain name is the dialog name unless overridden.
*)
method lookup : language:string -> string -> string
(** Looks up the meaning of a token in the given language. Raises
* [Not_found_in_catalog] if not found.
*)
method uplinks : string list
(** Returns uplink catalogs, in which one should look also to
* translate messages.
*)
method as_table : table
(** Returns the catalog as table. This is a secondary API which is
* needed to handle catalogs as values, but not to translate tokens.
* Uplink catalogs are not included in the table, i.e. looking tokens
* up via the table is not the same as calling [lookup].
*
* The table has the three columns [lang], [int], and [ext].
*)
end
class type extensible_message_catalog =
object
inherit message_catalog
method add_message : language:string -> string -> string -> unit
(** Adds the mapping of a token to a display string for a
* given language.
*)
end
(** This class type contains the dialog declaration *)
class type dialog_decl_type =
object ('self)
(* PUBLIC *)
method name : string
(** The name of the dialog *)
method enumeration : string -> enum_decl
(** Returns the declared enumeration *)
method variable_names : string list
(** Returns the names of all declared variables *)
method variable : string -> dialog_type poly_var_decl
(** Returns a single variable declaration *)
method page_names : string list
(** Returns the names of all declared pages *)
method page : string -> syntax_tree_type
(** Returns the XML tree of the demanded page (i.e. the [ui:page] node) *)
method page_is_declared_as_popup : string -> bool
(** Returns whether the page is declared as popup page (attribute
* [popup]
*)
method start_page : string
(** Returns the name of the start page *)
method default_context : syntax_tree_type dict
(** Returns the default context of the dialog, i.e. the context parameters
* that are declared by the [ui:context] element occurring directly in
* the [ui:dialog] element, and not in a certain page.
*)
method language_variable : string option
(** Returns [Some v] if a language variable called [v] is declared, or
* [None] if no such variable exists.
*)
(* RESTRICTED *)
(**/**)
method set_name : string -> unit
method set_start_page : string -> unit
method add_enumeration : enum_decl -> unit
method add_variable : dialog_type poly_var_decl -> unit
method add_page : string -> syntax_tree_type -> unit
method set_default_context : syntax_tree_type dict -> unit
method set_language_variable : string -> unit
end
(** This class contains the dialog instance *)
and virtual dialog_type =
object ('self)
method copy : dialog_type
(** return a copy of the dialog
*
* The copy is not attached to a session, even if the original object
* is.
*)
method name : string
(** return the name of the dialog *)
method page_name : string
(** return the name of the current page *)
method page_names : string list
(** returns the names of all defined pages of this dialog *)
method variable : string -> dialog_type poly_var_value
(** [variable n]: Get the variable with name [n], or raise
* [No_such_variable]. The name [n] cannot only refer to variables
* declared in this dialog, but also to variables of subdialogs
* using the dot notation: "name1.name2...nameN". Here, [name1]
* must be a dialog variable, and [name2] a variable of this
* subdialog, and so on, until the final variable [nameN] is
* reached, whose value is returned. - The dot notation is accepted
* by the following methods, too.
*)
method variable_decl : string -> dialog_type poly_var_decl
(* [variable_decl n] returns the declaration of the variable [n].
* Raises [Not_found] if there is no declaration. Note that the
* dot notation is allowed in contrast to [declaration # variable n].
*)
method initial_variable_value : string -> dialog_type poly_var_value
(** Returns the initial value of a variable *)
method string_variable : string -> string
(** [string_variable n]: Get the contents of the string variable [n].
* Raise [No_such_variable] if the variable does not exist. [Runtime_error]
* if the variable is not a string.
*)
method enum_variable : string -> string list
(** [enum_variable n]: Get the contents of the enumerator variable [n].
* The enumerator must have been declared. The returned list contains
* only the internal values.
* Raise [No_such_variable] if the variable does not exist. [Runtime_error]
* if the variable is not a declared enumerator.
*)
method dyn_enum_variable : string -> (string * string) list
(** [dyn_enum_variable n]: Get the contents of the enumerator variable [n].
* The enumerator may be dynamic or may be declared. The returned
* list contains both the internal and the external values.
* Raise [No_such_variable] if the variable does not exist. [Runtime_error]
* if the variable is not an enumerator.
*)
method dialog_variable : string -> dialog_type option
(** [dialog_variable n]: Get the contents of the dialog variable [n].
* Raise [No_such_variable] if the variable does not exist.
* [Runtime_error] if the variable is not a dialog.
*)
method alist_variable : string -> (string * dialog_type poly_var_value) list
(** [alist_variable n]: Get the contents of the associative variable [n].
* Raise [No_such_variable] if the variable does not exist.
* [Runtime_error] if the variable is not an alist.
*)
method matrix_variable : string -> head * string array array
(** [matrix_variable n]: Get the contents of the matrix variable [n].
* Raise [No_such_variable] if the variable does not exist.
* [Runtime_error] if the variable is not a matrix.
*)
method table_variable : string -> table
(** [table_variable n]: Get the contents of the table variable [n].
* Raise [No_such_variable] if the variable does not exist.
* [Runtime_error] if the variable is not a table.
*)
method function_variable :
string ->
( dialog_type ->
dialog_type poly_var_value Lazy.t list ->
dialog_type poly_var_value )
(** [function_variable n]: Get the contents of the function variable [n].
* Raise [No_such_variable] if the variable does not exist.
* [Runtime_error] if the variable is not a function.
*)
method lookup_string_variable : string -> string -> string
method lookup_enum_variable : string -> string -> string list
method lookup_dyn_enum_variable : string -> string -> (string * string) list
method lookup_dialog_variable : string -> string -> dialog_type option
method lookup_matrix_variable : string -> string -> head * string array array
method lookup_table_variable : string -> string -> table
method lookup_function_variable :
string ->
string ->
( dialog_type ->
dialog_type poly_var_value Lazy.t list ->
dialog_type poly_var_value )
(** [lookup_]*[_variable n x]: Get the contents of the associative
* variable [n] at index [x].
* [No_such_variable] if the variable does not exist.
* [Not_found] if the variable is undefined at [x].
* [Runtime_error] if the variable has the wrong type.
*)
method set_variable : string -> dialog_type poly_var_value -> unit
(** [set_variable n v]: Sets the variable [n] to the value [v]. The value [v]
* must be compatible to the declared type of the variable.
* [No_such_variable] if the variable does not exist.
* [Runtime_error] if the variable is not compatible.
*)
method unset_variable : string -> unit
(** [unset_variable n]: Sets the variable [n] to the declared default
* value.
* If the default is not declared, the following default values apply:
* For strings: the default is the empty string.
* For enumerators: the default is the empty list.
* For dialogs: the default is that the value does not exist.
*)
method lookup_uploaded_file : string -> Netcgi.cgi_argument option
(** [lookup_uploaded_file name]:
* Checks whether the file upload box [name] was used. If so,
* [Some arg], where [arg] is the transporting CGI argument is returned.
* If the box was not used, but the box exists, [None] is returned.
* Raises a [Runtime_error] if the named box does not exist.
*
* {b Important note:} Uploaded files are not persistent. This means that
* they are only existent in the [handle] phase, not during initialization
* nor the [prepare_page] phase. You get a failure
* "Upload.get: not initialized" if you try to access uploaded files
* in the wrong moment.
*)
method dump : Format.formatter -> unit
(** [dump f] output a textual description of the current state into
* formatter [f]. (A debugging aid.)
*)
method next_page : string
(** Returns the name of the designated next page. *)
method set_next_page : string -> unit
(** Sets the name of the designated next page *)
method event : event
(** returns the event that just has happened *)
method is_server_popup_request : bool
(** Returns whether someone invoked [set_server_popup_request] before.
* This is usually done if an dialog is restored for a server-driven
* popup window (tag [ui:server-popup]).
*)
method serialize : (dialog_type,unit) Hashtbl.t -> Buffer.t -> unit
(** Writes the state of this dialog into the buffer. The hashtable is used
* in the recursive descent into the object hierarchy to remember which
* dialogs have already been serialized. Call the method initially with
* an empty hash table.
*)
method unserialize : (universe_type,dialog_type,environment) poly_ds_buf -> unit
(** Sets the state of this dialog from the deserialization buffer which must contain
* previously serialized dialog.
*)
method enter_session_scope : session_type -> unit
(** Tells the dialog the current session *)
method leave_session_scope : unit -> unit
(** Tells the dialog that it is no longer under control of this session
*)
method session : session_type
(** Returns the current session. Fails when there is no session *)
method environment : environment
(** Return the environment of the current CGI activation *)
method declaration : dialog_decl_type
(** Return the declaration of this dialog *)
method application : application_type
(** Return the application *)
method universe : universe_type
(** Return the universe *)
(*********************************************************************)
(** {b The following methods must be defined in subclasses:} *)
method virtual prepare_page : unit -> unit
(** This method is invoked just before a new output page is generated.
*
* {b Preconditions:}
*
* The method [page_name] returns the name of this page.
* The method [event] still returns the action last happened, but
* the name of the page where this action happened is lost. It may
* be interesting whether the last event was [No_event] because this
* indicates that the page is the initial page of the dialog.
*
* This method should set any variables which are necessary to
* generate the new page (mostly variable containing HTML fragments).
* Furthermore, any state that needs to be saved should be put into
* variables, too.
*)
method virtual handle : unit -> unit
(** This method is invoked just after the user triggered an event (e.g.
* pressed a button).
*
* {b Preconditions:}
* The method [page_name] returns the name of the page that was visible
* while the event was triggered.
* The method [event] returns the description of the event.
*
* {b Postconditions:}
* The method may set the next page to display by invoking
* [set_next_page]; if it does not then the default will be used.
* The default is either specified by the XML element describing
* the interactor that triggered the event, or the default is
* otherwise this page again.
*
* This method should modify the variables according to the event
* that happened, and optionally set the next page to display.
*
* There is also an alternate way to go to another page: raising
* the exception Change_page.
*
* By raising the exception Change_dialog this method may force to go to
* another dialog.
*)
(*********************************************************************)
(**/**)
(* Internal methods *)
method set_event : event -> unit
(* set_event e: Sets the current event to e. *)
method set_server_popup_request : unit -> unit
(* Sets that this dialog is restored for a server popup window *)
method init : string -> unit
(* MOSTLY INTERNAL USE:
* init p: re-initializes the dialog in order to go to page p.
*)
method lock_ia : bool -> unit
(* ONLY INTERNAL USE *)
method interactors : interactors
(* ONLY INTERNAL USE *)
(* -- class [dialog] also has a private method:
* method private put_tree : string -> Template.tree -> unit
*)
end
(** This class represents the whole application *)
and application_type =
object ('self)
method start_dialog_name : string
(** Returns the name of the start dialog *)
method dialog_names : string list
(** Returns the names of the declared dialogs *)
method dialog_declaration : string -> dialog_decl_type
(** Returns the declaration for the passed dialog *)
method template_names : string list
(** Returns the names of the declared templates (including the templates of
* the core and the standard libraries)
*)
method template : string -> template_type
(** Returns the definition of the passed template *)
method study : unit -> unit
(** Studies all defined templates *)
method output_encoding : string -> (string -> string)
(** Returns the output encoding as function [string -> string] *)
method add_output_encoding : string -> (string -> string) -> unit
(** Adds the output encoding function (second argument) under the
* passed name (first argument) to the application. It is not
* possible to redefine existing functions.
*)
method var_function :
string ->
(dialog_type ->
dialog_type poly_var_value list ->
dialog_type poly_var_value)
(** Returns the function as O'Caml function.
* If the function has lazy arguments, this property will be lost when it is
* returned by this method. Use [lazy_var_function] instead.
*)
method lazy_var_function :
string ->
(dialog_type ->
dialog_type poly_var_value Lazy.t list ->
dialog_type poly_var_value)
(** Returns the function as O'Caml function *)
method dtd : Pxp_dtd.dtd
(** Returns the DTD of WDialog *)
method charset : Pxp_types.rep_encoding
(** Returns the character set used for the internal representation, and for
* the generated HTML pages.
*)
method debug_mode : bool
(** Returns whether there is a processing instruction [<?wd-debug-mode?>].
* This value is used to initialize the environment.
*)
method debug_mode_style : debug_mode_style
(** Returns the style of the debug mode *)
method prototype_mode : bool
(** Returns whether there is a processing instruction [<?wd-prototype-mode?>].
* This value is used to initialize the environment.
*)
method onstartup_call_handle : bool
(** Returns whether there is a processing instruction [<?wd-onstartup-call-handle?>].
*)
method add_var_function :
string ->
( dialog_type ->
dialog_type poly_var_value list ->
dialog_type poly_var_value) ->
unit
(** Adds a function with eager evaluation *)
method add_lazy_var_function :
string ->
( dialog_type ->
dialog_type poly_var_value Lazy.t list ->
dialog_type poly_var_value) ->
unit
(** Adds a function with lazy evaluation of its arguments *)
method catalog : string -> message_catalog
(** Return the catalog for the domain or raise [Not_found] *)
method add_catalog : message_catalog -> unit
(** Add an (external) catalog *)
method add_extensible_catalog : extensible_message_catalog -> unit
(** Add an extensible catalog. These can be extended by
* ui:catalog elements
*)
method add_message :
domain:string -> language:string -> string -> string -> unit
(** Adds a message to the extensible catalog identified by [domain].
*)
method lookup_message :
domain:string -> language:string -> string -> string
(** Translates the token to [language] starting with the catalog
* identified by [domain], and proceeding with uplink catalogs
* if necessary. Raises [Not_found_in_catalog] if no translation
* is possible.
*)
method data_source : string -> data_source
(** Gets a data source object or raises [Not_found] *)
method data_sources : data_source list
(** Get all data source objects *)
method add_data_source : data_source -> unit
(** Adds a data source *)
(**/**)
method set_start_dialog_name : string -> unit
method add_dialog_declaration : dialog_decl_type -> unit
method add_template : ?lib:bool -> string -> template_type -> unit
method set_debug_mode : bool -> debug_mode_style -> unit
method set_prototype_mode : bool -> unit
method set_onstartup_call_handle : bool -> unit
end
(** This class represents a template definition *)
and template_type =
object
method study : application_type -> unit
(** Studies the template for the scope of the passed application *)
method instantiate :
?context: syntax_tree_type dict ->
?vars: trans_vars ->
?params: syntax_tree_type dict ->
dialog_type ->
syntax_tree_type
(** Instantiates the template. The parameter [~context] may contain the
* context parameters (defaults to the empty set). [~vars] may contain the
* transformation variables (defaults to: not available). [~params] may
* contains the lexical parameters (defaults to the empty set).
* In every case, the current dialog instance must be passed.
*
* The result of the instantiation is the XML tree where all dollar notations
* have been replaced by the passed actual parameter values. It is not necessary
* that the template is completely expanded, however, i.e. it may contain
* [ui:use] elements.
*
* The exception [Instantiation_error] will be raised if something goes
* wrong.
*)
end
(** This class represents the XML syntax tree *)
and syntax_tree_type =
object ('self)
inherit [syntax_tree_type Pxp_document.node] Pxp_document.extension
(** The syntax tree is an extension of the PXP model for XML trees *)
inherit template_type
(** The syntax tree is always a template definition. This has formal
* reasons.
*)
(** {b Scanner methods}
*
* The side-effect of the scanners is to put the result into the passed
* argument.
*)
method scan_application : application_type -> unit
method scan_dialog : application_type -> dialog_decl_type -> unit
method scan_enumeration : enum_decl -> unit
method escaped_data : string
(** Returns the string contained in the data node after HTML-escaping has
* been applied. This string is cached.
*)
method to_html :
?context: syntax_tree_type dict ->
?vars: trans_vars ->
dialog_type ->
Netchannels.out_obj_channel ->
unit
(** This method writes the current node and all its children to the passed
* output channel. This method is for HTML context, i.e. character data
* are to be HTML-escaped, and all elements have to be interpreted.
*)
(* TODO: to_xhtml *)
method to_text :
?context: syntax_tree_type dict ->
?vars: trans_vars ->
dialog_type ->
Netchannels.out_obj_channel ->
unit
(** This method writes the current node and all its children to the passed
* output channel. This method is for attribute context, i.e. character data
* remain as they are without escaping them, and only the elements are
* interpreted that are defined for attribute context.
*)
end
(** The universe is the registry of classes and dialogs *)
and universe_type =
object ('self)
method application : application_type
(** Return the application this universe is made for *)
method register : string -> (universe_type -> string -> environment -> dialog_type) -> unit
(** Registers that a certain O'Caml class implements the callbacks of the
* dialog declared in the UI definition. More precisely,
*
* [u # register name f_new]
*
* registers that the dialog [name] is realized by the objects returned by
* the evaluation of the constructing function [f_new]. The arguments passed
* to [f_new] are:
*
* [f_new u name env]
*
* where [u] and [name] are the universe and the dialog name, and [env]
* is the environment of the current CGI activation. It is legal to store
* [env] in the created objects because they are created for every activation
* anew.
*)
method create : environment -> string -> dialog_type
(** Creates a new object for the passed environment and dialog name. This method
* effectively calls the function [f_new] that has previously been registered.
*)
end
(** The session manager creates new sessions, and looks sessions up in the
* (possibly fictive) session database
*)
and session_manager_type =
object
method create : dialog_type -> session_type
(** Creates a new session for this dialog *)
method unserialize : universe_type -> environment -> string -> session_type
(** Restores an old session for the passed universe and the passed
* environment. The string is the session in serialized form as returned
* by the [serialize] method.
*)
end
(** This is a single session *)
and session_type =
object
method session_id : string
(** Returns the ID of the session. Fails if the session does not have
* an ID (e.g. it is not stored in the database)
*)
method dialog_name : string
(** Returns the name of the dialog this session encapsulates *)
method dialog : dialog_type
(** Returns the dialog *)
method commit_changes : unit -> unit
(** Causes that [serialize] returns the current state of the dialog.
* This means that [commit_changes] extracts the state from the dialog,
* and prepares the string that will be returned by [serialize].
*)
method serialize : string
(** Returns the state of the dialog at the time of the last [commit_change]
* or the state of the initial dialog
*)
method change_dialog : dialog_type -> unit
(** Continue with a new dialog. The methods [dialog_name] and [dialog] will
* immediately reflect the change. However, you have to call [commit_changes]
* to make [serialize] return the state of the new dialog.
*)
end
and data_source =
object
method name : string
(** The name of the data source, e.g. "sql" *)
method pre_handle : dialog_type -> unit
method post_handle : dialog_type -> bool -> unit
method pre_prepare_page : dialog_type -> unit
method post_prepare_page : dialog_type -> bool -> unit
(** Hooks. The [bool] argument is [true] when the method was successful. *)
method retrieve : string -> table
(** Retrieves the data for an expression of the data source provider
* as table (think SQL SELECT statement).
*)
end
type var_value = dialog_type poly_var_value
(** [ ]
*
* This type is the concrete version of {!Wd_types.poly_var_value} that is
* actually used
*)
type var_decl = dialog_type poly_var_decl
(** [ ]
*
* This type is the concrete version of {!Wd_types.poly_var_decl} that is
* actually used
*)
type ds_buf = (universe_type,dialog_type,environment) poly_ds_buf
(** [ ]
*
* This type is the concrete version of {!Wd_serialize.poly_ds_buf} that is
* actually used
*)
exception Change_dialog of dialog_type
(** The implementation of the [handle] method of a dialog may raise
* [Change_dialog] to drop the current dialog and continue with another
* dialog.
*)
exception Change_page of string
(** The implementation of the [handle] method of a dialog may raise
* [Change_page] to set the next page to display for the current dialog.
*)
exception During_action of string * exn
(** The inner exception occurs in the action described in the string *)
exception Formal_user_error of string
(** A formal error that happens independently of the current runtime state.
* The string argument explains the error.
*)
exception Runtime_error of string
(** A certain operation cannot be performed because the current state does
* not fulfill the necessary preconditions.
* The string argument explains the error.
*)
exception No_such_variable of string
(** It has been tried to access a non-declared variable. The string is the
* name of the variable.
*)
exception Instantiation_error of string
(** An error generated by the [instantiate] method. The caller should
* catch this exception and report the error from its own view
*)
exception Eval_error of string
(** An error generated when evaluating bracket expressions. The caller should
* catch this exception and report the error from its own view
*)
exception Eval_error_noloc of string
(** An error generated when evaluating bracket expressions. The caller should
* catch this exception and report the error from its own view.
* In contrast to [Eval_error], this exception does not contain any
* reference to the location of the failed expression.
*)
(**/**)
val revision_types : string
(* Returns the CVS revision string. It is part of the hash value
* that goes into the serialized objects
*)
(* ======================================================================
* History:
*
* $Log: wd_types.mli,v $
* Revision 3.14 2006-03-08 00:56:45 stolpmann
* Addition of Table_value, Matrix_value and Function_value.
*
* New parser for initial expressions. It is now possible to
* use $[...] in variable initializers.
*
* Extended bracket expressions: functions, let expressions,
* word literals, matrix literals.
*
* New type for message catalogs, although not yet implemented.
*
* Revision 3.13 2005/12/09 20:02:40 stolpmann
* Fix in Wd_interactor.unserialize.
*
* The [interactors] are now locked in the "handle" stage of processing.
* Any trial will fail.
*
* Revision 3.12 2005/06/11 14:24:14 stolpmann
* Extension of bracket expressions: many new functions.
* Functions in bracket expressions may now lazily evaluate their arguments.
* ui:if and ui:ifvar may refer to any functions defined for bracket
* expressions.
* New: ui:ifexpr
* Parsing of bracket expressions is now done with ulex. Private interfaces
* of PXP are no longer used for this purpose.
* Serialization has been rewritten, and it is now safe.
* Fix: In ui:context there may now be macro references at any location.
* Also documented all these changes.
*
* Revision 3.11 2004/12/12 17:57:32 stolpmann
* Added <q:wd-link> and <q:wd-xlink> to generate links for
* applications that cannot use Javascript. Limited functionality, however.
* See stdlib.xml for details.
*
* Revision 3.10 2003/03/21 14:23:44 stolpmann
* ocamldoc updated
*
* Revision 3.9 2003/02/21 21:58:53 stolpmann
* Changed docs.
*
* Revision 3.8 2003/02/16 23:48:15 stolpmann
* Improved wd-debug-mode: there are now two styles
*
* Revision 3.7 2003/01/04 21:55:26 stolpmann
* new record response_header
*
* Revision 3.6 2002/11/09 11:41:19 stolpmann
* Fix: ui:select accepts dot notation. A new method
* variable_decl needs to be defined for dialogs. This method
* returns the var_decl record and interprets the dot notation.
*
* Revision 3.5 2002/10/20 19:39:17 stolpmann
* New feature: The brackets $[...] can contain expressions,
* not only variables
*
* Revision 3.4 2002/10/18 20:17:49 stolpmann
* New feature: dot notation to access contents of dialog
* variables
*
* Revision 3.3 2002/04/10 20:04:05 stolpmann
* The CVS revision number is exported.
*
* Revision 3.2 2002/02/14 16:15:21 stolpmann
* Added copyright notice.
*
* Revision 3.1 2002/02/12 20:29:25 stolpmann
* Initial release at sourceforge.
*
* Revision 2.1 2002/02/11 18:27:55 gerd
* Initial revision.
*
*
*)