SurferScript integrates with Cold Fusion, ASP, XML and EJB Co-Servers with three key SurferScript tags: the <TESECTION> tag, the <TEDECLARE ROW> tag and the <TERESULT> tag. An additional tag is useful for documentation and development with the DevCenter, which is the <TEDECLARE RPC> tag.
To implement Co-Server transactions in Visual Surfer:
Should the high-level facilities of the Visual Surfer environment not provide enough flexibility, it is recommended that you rename the PML module that acts as your Transaction definition, and then edit the STML file generated by the PML module-- in this manner, you can exploit the code-generation capabilities of Visual Surfer while not being limited by it.
If you find that you need to extend the scripts generated by Visual Surfer...read on!
Support for co-server applications on a transaction basis (parameters passed in, named fields, queries and recordsets returned) requires a set of ScreenSurfer transactions which work with a defined set of screens, all of which have been described using <TESECTION> tags.
Input Parameters are passed by the co-server components as either CFX tag attributes (Cold Fusion) or using SSurfer.ASPRequest AddInput() method calls (ASP), or EJB's addInput() method calls. In SurferScript, all input parameters may be queried and utilized as web.name variables. A web. variable is a readonly variable that accesses all input for the current request (like a combination of the QUERY / FORM / CONTENTS containers in other web development environments).
Results are returned to the co-server component using one or more TERESULT tags. To return structured, named data fields, a row of data is defined using TEDECLARE ROW. Individual fields in the row are set using TESET, and a completed row (all fields set) is returned using TERESULT ROW. Using a TERESULT ROW by itself will return a single-row query (CF) or RECORDSET (ASP/EJB) to the co-server component.
To return a table of more than one row (QUERY for Cold Fusion, RECORDSET for ASP/EJB), you open the table first using TERESULT TABLE, specifying the ROW that you will be filling the table with (the row being one that was declared using TEDECLARE ROW). Then, as with the return of single-row results, you set each row field using TESET, and when the row is ready, send it as part of the active resultset using TERESULT ROW. A typical situation where a table would be returned is a screen with multiple rows; each containing fields for a unique entity. For this situation, you can use a TERESULT TABLE, then a TELOOP containing a number of TESET tags to copy from the current row to the defined result row and a TERESULT ROW to return the individual row to the co-server component.
To pass-through ScreenSurfer generated HTML (an entire screen for example), you use the TERESULT HTML which will "open" a named attribute for the co-server component where all subsequent HTML SurferScript will be written. To pass-through this HTML in the individual component, the attribute is displayed in the current page like any other variable (it will be a BIG text attribute!).
Note that due to limitations in the access to HTTP variables in a CFX tag, full passthrough is presently only supported for ASP co-server environments. In a Cold Fusion environment, this means that when you pass-through ScreenSurfer HTML that includes data entry forms, you will need to "hand-code" the transfer of all ScreenSurfer form entries on through to the CFX tag. In the ASP environment, the ScreenSurfer component has access to all HTTP variables, and "grabs" the ScreenSurfer values with a single method call.
Screen Navigation
Screen navigation for managing requests is best implemented using the TEREADYWHEN tag combined with the TEACTION ENTER tag.
The TEREADYWHEN Strictrecognition tag enables you to "prime" the next screen transition, so that in the procedural environment of navigating through multiple logon and application screens there is full synchronization between ScreenSurfer and the host. The TEREADYWHEN tag is optional, and is usually only required during logon sequences or top-level application system selection menus. Once in an application environment, such as CICS, you will only need the TEACTION ENTER to navigate from one screen to another, as the screen transitions are very reliable.
The TEACTION ENTER tag is used to directly control navigation from one screen to the next. Remember to use the SkipCode attribute when using TEACTION ENTER, to prevent ScreenSurfer from executing the script connected to Global.Default or a screen you have identified in a TESECTION.
Complete Transaction and Navigation Example | |||
---|---|---|---|
| |||
|
Since SurferScript supports the ability to call any number of sections as part of an individual request, sections should be developed specifically for managing screen navigation. For example, a section can be written which "knows" how to navigate to a "home" screen (either a command screen or a main menu) from any supported screen. This then can be used at any time to request a new function, regardless of where the last transaction left the application.
Typically, a transaction will start at this "home" screen-- when a session is newly started, a SurferScript section can be called to perform a logon to navigate correctly to the "home" screen. From the home screen, any number of host screens can be visited, with the data on the screens either entered from parameters passed by the co-server component (all input parameters passed are available as web.valuename variables). Note that navigation may be achieved using not only parameters passed in the current transaction request, but also any state variables declared using TEDECLARE and set using TESET.
The anonymous request environment involves sessions that are logged-on to the host using either a "dummy" userid/password. Note that if there are restrictions on the number of sessions an individual user can use: userids can be constructed using a base text and the Screen.SessionID variable, which is a number corresponding to the session number defined in the Console Settings Page.
Session Management
While you can mix and match session approaches with ScreenSurfer and co-server components, we will describe the two major session approaches here. The first approach is what we will call "anonymous requests". The second approach is "owned sessions".
Anonymous request environments have a transaction sequence that roughly follows the following steps:
The owned sessions environment is one where each co-server "application session" or "user" needs to logon with his or her own userid/password and own a specific session for the duration of the application. With owned sessions, the SessionKey is an important attribute that must be maintained in the co-server application, either as an application-level variable, a client-side cookie or in individual URL cookies. This is because the SessionKey is the connection between the co-server session, the host screen session and all the SurferScript session variables.
Owned Session environments typically implement the following steps:
Note that you can have a number of "housekeeping" tranactions which break-out some of the above logic. For example, a "GetNewSession" transaction might be used to acquire a new session, driven by logic at the co-server. Also, an "ExitSession" transaction may be triggered by the user ending a session at the co-server, to free-up the session in ScreenSurfer and log the user off the host.
Co-Server Tag Reference
The following sections detail how to use each tag involved in supporting co-servers.
<TEDECLARE ROW [name=]{name} {variable 1 declaration} [variable n declaration] [...]>
Defines a row of SurferScript variables which will be returned either as simple variables using <TERESULT ROW> (not in a multirow return) or as a table using <TERESULT TABLE> and multiple <TERESULT ROW> tags (multiple rows).
TEDECLARE ROW Example 1 | |||
---|---|---|---|
| |||
|
TEDECLARE ROW Example 2 | |||
---|---|---|---|
| |||
|
<TERESULT {TABLE | ROW | HTML | XMLDOC | XMLPUSH | XMLPOP | JAVASCRIPT} ...>The TERESULT tag has five major types, the TABLE, ROW, HTML, XMLxxx or JavaScript. Each of these is described in the following sections.
<TERESULT [type=]TABLE [[row=]RowOrScreenMapName [[name=]"XMLEntityName"]>The TABLE result initiates a multirow result-set. The ROW attribute is used to specify the name of the TEDECLARE ROW or TEDECLARE SCREENMAP definition used to output each row of the table.
For a ColdFusion CFX tag, the result set will be returned as a QUERY (can access in a <CFOUTPUT> block) which has the name of the <CFX_SURFER Name="name"> attribute combined with an underscore and the RowName defined in the <TERESULT> tag. The names of the columns in the query will match the names in the named row.
For a SSurfer.ASPRequest or Surfer EJB object, a RecordSet with the same name as the RowName will be returned, containing fields matching the names in the named row.
For an XML-over-HTTP caller, an entity open tag is opened, with the name of the row or screenmap followed by the string "Table" as the entity name (for example, a row named "Person" would open a "<PersonTable>" tag. For XML output, the name= attribute can be used to name the open tag something different than the row name. For example, using <TEResult Table row=Person name="People"> will open an entity as <People> rather than <PersonTable>.
Following the <TERESULT TABLE RowName> tag, you typically will execute at least one <TERESULT ROW>, and usually more than one (you can use the <TELOOP> tag to control looping down a screen when multiple rows need to be returned).
If the TERESULT ROW name matches the name given in a preceeding TERESULT TABLE, the row returned will belong to that table (or XML Entity). If not, the row is simply returned, and will be added to the BASE query or recordset for the current request (or added as single-level entities to the root XML document).
If no TERESULT TABLE is issued during the current transaction, all row fields returned will be added to the base query/recordset/root document. The base recordset has the same name as the active query in ColdFusion and has a name of "Base" for SSurfer.ASPRequest and the Surfer EJB.
For XML-over-HTTP results, the optional Name attribute can be used to name the opening entity tag something different than the name of the row.
XMLAttrs=Yes will cause all the variables in the row/screenmap to be included in the output entity as name/value pair attributes. By default (unless XMLPush=Yes is used), the Entity tag will be closed automatically at the end with a "/>".
XMLPush=Yes will prevent the "close of the entity" represented by the row from occuring (no /tag at end for a standard result or no / at the end of an attributes-style tag.
The default behavior for XML output is to have an opening entity tag with the name of the row or the optional XMLEntityName, followed by an entity open-body-entity close sequence for each variable defined in the row or screen. For an XML example, see XML Row Output Sample.
TERESULT ROW
<TERESULT [type=]ROW [[row=]RowOrScreenMapName [[name=]"XMLEntityName"] [XMLPush="Yes|No"] [XMLAttrs="Yes|No"]>
The ROW result outputs a row that has been initialized using one or more TESET tags (one per row variable) or a SCREENMAP that has been initialized using the <TEGetScreen...> tag. The ROW attribute is used to specify the name of the TEDECLARE ROW/SCREENMAP definition to be output.
TERESULT TABLE and ROW Example | |||
---|---|---|---|
| |||
|
TERESULT HTML Example | |||
---|---|---|---|
| |||
|
Note that is your output in an XML-over-HTTP call starts with a TEResult XMLPush, it will override the name of the root document which as a default is named <Results>. So, to override the root document name use the TEResult XMLPUSH prior to any other TERESULT tags in your script.
For a row named "Person" a Javascript array named nvPerson will be defined, and for each variable in the row or screenmap, a named element will be added to the array. For example, if the Person row contains three variables, "Name", "Height" and "Weight" and the values in these variables are "Windsurfer", "6-2" and "210" then the following javascript will be emitted:
Where:
TERESULT XMLPOP>
Will close the current entity. Note that an XML entity is opened using any of the following tags:
<TEResult XMLPush name="EntityName">
(output = <EntityName>)
<TEResult Row RowName XMLPush="yes">
(output = <RowName>...variable entities...)
<TEResult Table RowName>
(output = <RowNameTable>...then TEResult Row's...)
TERESULT Javascript>
When embedded in a SCRIPT block, this can be used to easily transfer named javascript variables to a javascript array as "name/value" pairs so that the variables can easily be accessed in a dynamic manner in other script on the HTML page.
var nvPerson=new Array();
nvPerson['Name']='Windsurfer';
nvPerson['Height']='6-2';
nvPerson['Weight']='210';
Note that the value "Height" from person can be accessed in any javascript expression using nvPerson['Height'].
TEDECLARE RPC Define the interface for a co-server transaction
<TEDECLARE RPC [Parameters=]"Parm1,Parm2,..." [Results=]"row1,row2,..."
[Description=]"Description">
Parameters | The expected input, with each parameter name separated with a comma--since some transactions do not require any input parameters, this attribute is optional. Use the Description to identify if any declared parameters are optional/required, as a comment. |
Results | Returned results--this is a comma separated list of the rows that can be returned by this transaction in a TEDECLARE ROW. If a row is returned as part of a table, preceed its name with an underscore to indicate a full table return. (TERESULT TABLE preceeds one or more TERESULT ROW tags). |
Description | Freeform text used to describe this call to a developer viewing a list of calls in a DevCenter Co-server code generation wizard. Essentially a comment. |
TEDECLARE RPC Example | |||
---|---|---|---|
| |||
|