WDialog provides a programming model taken from object-oriented GUI programming, and adopts this model to HTTP-based Web applications. In the following paragraphs, I try to explain the WDialog model, the similiarities to the GUI model, and the differences to other Web application concepts.
From the GUI model to WDialog
Picture 1 outlines some architectural aspects of traditional graphical user interfaces. Usually, there is a window object (or several objects) for every displayed window. The window object is the base object for programming, and implementing a certain window behaviour means to override methods of the object. The window system manages it to connect the window object to a real input/output device (i.e. an area of the screen, mouse, keyboard). User input (keystrokes, moving the mouse etc.) is translated into a stream of events sent to the window object. Conversely, the window object can send display requests to the window system.
Picture 1: The GUI programming model
The window object and the real window exist as long as the session remains open. It is important to mention that there is a session, as this is one of the problems with Web-based applications.
The window object stores internally some state. The state reflects both the current step in the dialogue with the user as well as the data the window displays.
Picture 2 shows the architectural constraints of HTTP-based applications. The browser and the HTTP server communicate via HTTP, and the server finds the right Web application (which is usually a separate program) and invokes it. There is no normative protocol for the invocation of the Web application, but the most popular is certainly CGI.
Picture 2: HTTP-based applications
The requests (HTTP or application) play a similar role as the events in the GUI model; they normally indicate user interaction. In the same manner, the responses can be compared with the display requests. However, there are some fundamental differences between both models which makes it difficult to simulate the GUI model on top of an HTTP architecture.
In contrast to the GUI architecture discussed above, there are no sessions. The HTTP protocol isolates consecutive request/response cycles from each other. The protocol does not give any hint whether several such cycles belong to the same logical series of interactions, or whether they are unrelated.
Furthermore, there must always be a response for every request in HTTP. The response normally replaces the previous response, it is not possible to transfer only the parts of the page that have changed (for example, to add some rows to an HTML table). The response is a function of the request, and only of this single request. This is different from the GUI model that tries to only exchange delta information between the window object and the window system.
The strict request/response scheme means that the Web application works like a function that processes the request and produces the response. The application protocol connecting the Web application with the HTTP server reflects the functional behaviour. If CGI is used as application protocol, every invocation of the Web application is perfomed in a separate process such that the operating system already guarantees that invocations do not interfer.
The idea of WDialog is to simulate aspects of the GUI model in the HTTP architecture. Picture 3 illustrates this: The WDialog library (linked as part of the application) creates the illusion of a window object communicating with an application window. The window object receives events if the user presses buttons or clicks at hyperlinks, and the window object sends display requests to the application window. Of course, the illusion is not perfect, and there are many restrictions compared with the GUI model.
Picture 3: The WDialog architecture
In reality, the application window is an ordinary browser window displaying HTML pages. The HTML code is mixed from two sources: On the one hand, the application programmer designs the visual layout of the page, and writes an algorithm that creates the necessary HTML elements implementing the desired look. On the other hand, some of the HTML code is generated by WDialog because it is needed to simulate the GUI model. In order to mix the elements from the two sources accordingly and in a predictable manner, WDialog evaluates a special code block called User Interface (UI) Definition. This is an XML file containing normal HTML elements for the visual layout, and special "ui" elements that are going to be replaced by simulation code during page processing. For example, the page
<html> <body> <ui:form> This page has a <ui:button name="b" label="button"/>. </ui:form> </body> </html>contains the special elements ui:form and ui:button. ui:form establishes the simulation environment needed for ui:button, as it is transformed into a HTML FORM element with additional parameters referring to the current state of the simulation. ui:button is transformed into a HTML INPUT element that is able to send a "button press" event to the application in a way that can be uniquely decoded by WDialog. The overall effect is that the application has the illusion that the browser understands all the ui elements, or in other words, that the browser provides an application window that can be programmed in the GUI style.
The window object is modeled using the object-oriented features of the underlying programming language; however there is one important difference to the corresponding objects in the GUI model. The window object exists as object of the programming language only from time to time, especially in the moment the response is computed from the request. As already pointed out, the response must be a function of the request, and because of this, it is not possible that the object persists between two consecutive request/response cycles, for example in a background store. However, the object must be persistent, and the solution is that the object is serialized (as a stream of bytes) and transferred within the request and response messages. Every time the application receives a request, the WDialog input transformer deserializes the object, and awakes it again as object of the programming language. Conversely, the output transformer serializes the object and includes it into the outgoing response message. In HTML the so-called hidden form fields can be used to transfer such an invisible data field in the request and response messages. Actually, these form fields are generated as part of the mentioned ui:form transformation.
The effect of this serialization technique is that the object seems to be persistent. However, the illusion is far away from being perfect; the instance variables of the object need to be declared in a special way such that the WDialog library knows which variables make up the object. If the application code uses other instance variables, these are lost between consecutive cycles.
Of course, the simulation cannot break with the strict nature of the request/response cycles, i.e. that every HTTP request must be followed by a complete response. However, the WDialog library implements several techniques making life easier. For example, the application needs not to analyze requests; the WDialog library already does it, and the results are automatically stored in the window object. Requests are handled as if they were events, and the WDialog library extracts button events, hyperlink events and so on from the arriving request messages. Mutable interactors like text input boxes must be tied to instance variables of the window object. This means that the contents of the interactors are initialized from the current value of the corresponding instance variable, and that user changes of the contents are automatically propagated back to the variable.
The composition of response messages is simplified by the user interface (UI) definition language. As already pointed out, the application can (and must) use the abstract ui elements hiding implementation details of the simulation. These ui elements are part of the UI language among others (all have the ui prefix). For example, the HTML code is grouped into so-called pages. A page can be seen as an output method of the window object, and it generates the whole HTML document that is displayed in the browser window. It is possible to have several ui:page sections, and this can be used to provide different visualizations of the same state. The following XML file shows a complete UI document; the application reads such a file in order to get the declarations of the objects and to get the definitions of the pages:
<?xml version="1.0"?> <!DOCTYPE ui:application PUBLIC "-//NPC//DTD WDIALOG 2.1//EN" ""> <ui:application> <ui:dialog name="sampledialog"> <ui:variable name="v1"/> <ui:variable name="v2"/> <ui:page name="order12"> <html> <body> <h1>Variables in order 1, 2:</h1> v1: <ui:dynamic variable="v1"/> v2: <ui:dynamic variable="v2"/> </body> </html> </ui:page> <ui:page name="order21"> <html> <body> <h1>Variables in order 2, 1:</h1> v2: <ui:dynamic variable="v2"/> v1: <ui:dynamic variable="v1"/> </body> </html> </ui:page> </ui:dialog> </ui:application>This file defines one dialog (window) object sampledialog containing two instance variables v1 and v2 (these are string variables by default). (In the rest of this manual, the term dialog object is preferred over window object. This stresses the role of dialogs as the link spanning the individual page invocations. It is the series of interactions that counts, not the single web page.) There are two pages: order12 visualizes the dialog object by first displaying v1 followed by v2, and order21 shows the variables in the reverse order. When the application wants to send the response message to the browser, it simply selects one of the defined pages of the object, and delegates the details of sending the message to the WDialog library. (This is done by the already mentioned output transformer.)
The components of a WDialog application and how they interact
The application consists of the following major components:
At startup, the application invokes the initialization function of the WDialog library which loads the UI document. By default it is assumed that the application is connected via CGI to the HTTP server, and the library is set up for this environment. However, it is possible to integrate the application into other environments .
The next step of the application is to connect classes of the program with the dialogs occurring in the UI document. Besides pages, the UI document declares only the instance variables of the dialog objects, but not methods for other purposes. The WDialog library has a registry associating classes of the program with dialogs of the UI definition. After the registration has been performed, the WDialog library is able to deserialize arriving dialog objects and to represent them as ordinary objects of the program. Furthermore, the library can now invoke methods on the objects; there are two methods with predefined meaning: prepare_page and handle (see below). Last but not least it becomes possible to serialize the dialog object again.
The application calls now the process_request function of WDialog doing all the rest. The result of this function is the response message that is sent to the HTTP server. See the illustration in picture 4.
Picture 4: Steps of the process_request function
process_request first analyzes the request. The current object is deserialized, and in the following, the other information included in the request are stored into the object: The event is extracted from the request, and all changes to user-modifiable interactors are processed (normally by setting the corresponding instance variables of the object).
The next step is that the method handle of the current object is invoked. This method is fully customizable as it is implemented as ordinary object method; its task is to react on the last event. For example, if the application allows users to enter data records, one possible event (button) is "Store this record". An implementor of handle would get the entered record (from the instance variables), and put these data into a database.
The handle method must also determine what has to happen next; we still need a response. One possibility is to select one of the pages (output methods) of the current object. Alternatively, a different object can be created, initialized, and a page from this object can be selected (not displayed in the picture).
Once the page is known, the library could immediately output the contents of the page. However, before output starts, the method prepare_page is called; this method is an ordinary method of the object, too. The programmer has the opportunity to set instance variables of the object that are needed for the visualization. For instance, if the application allows users to query data records, the prepare_page method will perform the query on the database and write the resulting records into instance variables of the object.
Finally, the selected page is actually transformed to HTML and sent to the HTTP server. This operation includes the serialization of the current object.