|
Contents: Completing Your Application Completing Your Application The previous sections have explained how to develop the client side of an application, which deals primarily with the user interface. Now we turn to the host side, where additional business logic will be written to create data extracts to download to the mobile device, and to process transactions uploaded from the device, such as new sales orders, warehouse inventory movement, etc. All programs on the host are written in a language specific to the host environment. Examples include: VBScript for Microsoft ASP pages, the Progress 4GL for Progress Software environments, PL/SQL for Oracle environments, PHP scripts for Linux, Unix and Windows, and Java for J2EE environments. In fact, any language that supports HTTP request/response protocols (either directly or via some other middleware product) will work for the host side code. For host language environments that do not provide HTTP support, you can still interact with the mobile client by using FTP to upload and download text files containing the required data in some format, such as CSV files. While this will work just fine, you do lose most real-time interactivity capabilities with this more batch-oriented approach. When designing your application, you should consider and answer the following questions at the outset: 1. Will any of the processing be done in a state-aware mode, or will all processing be "stateless"? This is probably the most important issue that must be answered up front, as it has a major impact on the number of host processes that will be needed for a given transaction workload and on how the host and client sides will be designed. See the sections below on writing host procedures for more details on the issues involved with this decision.
Jargon Writer can automate some of the creation of the host programming for you by generating template code for one or more host procedures that handle the receiving and parsing of the parameters sent from the client to the host for each host request. When you have completed the definition of each host request in your client application, you are ready to generate the host source procedure files. This feature generates "template" source code for host procedure(s) that are run by http requests from this app. Code generation is done by a separate app that is specified by the "SourceCodeGeneratorApp" preference value in the "writer.ini" file. All generated files are placed in the folder specified by the "4GLRootDir" preference. Currently, Jargon Writer includes a SrcCodeGenP4GL.xml generator for developing apps that will communicate with host procedures written in the Progress 4GL. It generates one or more Progress ".p" source programs, based on the specs and parameters in http requests that were defined in the Script Editor for the currently active app. Other generators can be written for other host language environments such as Microsoft ASP pages, Oracle PL/SQL procedures, PHP scripts, etc. by using the included generator as a model. If you are interested in writing a source code generator for Oracle PL/SQL, PHP, Microsoft ASP, Java servlets, or for any other host environment, please contact Jargon Software (email support@jargonsoft.com) For the automated code generation to work correctly, each host request must be defined within a separate function, starting with a call to "MakeURL", followed by zero or more "http.AddParam" statements for any host parameters, and ending with an "http.SendRequest" statement. Here is a simple example of a script with one host request ("GetCust"):
// GLOBAL VARIABLES
var thisApp = 'cust';
var HostProg = 'examples/cust.p';
var UseSSL = false;
// GENERIC FUNCTIONS, DEFINED ONCE
function MakeURL(program, procedure) {
var HostURL = preference.GetPreference('HostURL');
var Script = preference.GetPreference('Script');
http.SetNotifyProc(thisApp, 'NotifyCmdsRecvd');
http.SetURL(HostURL + '/' + Script + '/' + program);
http.AddParam('ProcName', procedure);
}
function NotifyCmdsRecvd() {
if (! http.GetSuccess()) {
sys.WarningBox('Host returned an error status');
return;
}
var rcvSize = http.GetResponseSize();
if (rcvSize > 0) sys.ProcessInstructions(http.GetResponseData());
}
// APPLICATION-SPECIFIC FUNCTION TO SEND A SPECIFIC HOST REQUEST
function GetCust(CustID) {
UseSSL = (preference.GetPreference('UseSSL') == 'true');
MakeURL(HostProg, 'GetCust');
http.AddParam('tCustNum', CustID);
http.SendRequest(UseSSL);
}
The steps to follow are straightforward:
IMPORTANT: If you have a Windows client and a Unix/Linux host, be sure to specify "text" mode (not "binary" mode) in FTP, before transferring the file. Since a host program is a text file, each line is delimited by some special character(s). On Windows systems, this is a CR/LF character pair, but on Unix/Linux, it should only be a LF character. (LF means line feed which is decimal "10"; CR means carriage return which is decimal "13"). In binary mode, FTP will not strip out the CR characters when uploading a text file from Windows to Unix/Linux, and this may cause a variety of problems which you are better off not experiencing firsthand.
/* demo/cust.p */
Generated on Jun 10, 2005 at 9:48:31 AM CST.
Do not modify this code! Use Jargon Writer to re-generate.
*/
{jsi/dispatch.i}
{jsi/getprocs.i}
/* top-level include file for temp-tables and other functions/procedures */
{demo/cust.i}
procedure getcust:
def var tCustNum as int no-undo.
{jsi/getint.i &fieldname='tCustNum' &targetvar=tCustNum}
{jsi/output.i}
{demo/cust/getcust.i} /* Business Logic goes into this include file */
end procedure.
procedure setcust:
def var tCustNum as int no-undo.
def var tCustName as char no-undo.
def var tLastOrderDate as date no-undo.
def var ckOnCreditHold as logi no-undo.
def var tCreditLimit as dec no-undo.
{jsi/getint.i &fieldname='tCustNum' &targetvar=tCustNum}
{jsi/getchar.i &fieldname='tCustName' &targetvar=tCustName}
{jsi/getdate.i &fieldname='tLastOrderDate' &targetvar=tLastOrderDate}
{jsi/getlog.i &fieldname='ckOnCreditHold' &targetvar=ckOnCreditHold}
{jsi/getdec.i &fieldname='tCreditLimit' &targetvar=tCtCreditLimit}
{jsi/output.i}
{demo/cust/setcust.i} /* Business Logic goes into this include file */
end procedure.
Host Communications Parameters
For some tasks that may be all there is to it -- no other parameters are needed. Examples might be a host request which kicks off a host report program that has no options, or a batch update program that likewise needs no options. In these examples, the host processing logic is "hard-wired". However, most host requests will require one or more data parameters in order to accomplish the desired processing logic. As discussed above, a common parameter is a User ID or session ID of some kind, which is used both for security purposes and to access context information that may have been saved (in the database or elsewhere) from a previous interaction. For an inquiry ("get") task, the client might supply a customer number as a parameter, so that the host request can find that customer in a database table and send back the customer's name and address values to be displayed on the client screen. For an update ("set") task, the client will send all data fields that the user may have filled in, so that the database can be updated with these values. Many other scenarios are also possible. Each parameter sent by the client can be a constant, or it can be a result of invoking some method on a client component object, such as getting the current value of a quantity textfield. All parameters will be used to populate a corresponding variable or input parameter in the host procedure. The data type (character, integer, decimal, date, logical) of the input parameters or variables must match the corresponding data type of the client component or constant. Note that for the Progress 4GL, the "logical" data type is referred to as "boolean" in Jargon Writer. All values of buttons, checkboxes and radio buttons are mapped to logical variables. Current selection values for comboboxes and listboxes are mapped to character variables. Writing Stored Procedures in Oracle PL/SQL Oracle PL/SQL stored procedures can be coded without using a generator. For an example, see the "Oracle/demo/SQL/empdemo.sql" demo procedure included in the Jargon Writer installation directory. This working example has been tested with Oracle's Application Server. Oracle middleware passes http input parameters as input parameters to the PL/SQL procedure named in the host request. Here is a header for a procedure that displays employee information for an employee number sent as a parameter in a host request that names this procedure (DisplayEmp):
PROCEDURE DisplayEmp(nEmpNo IN NUMBER) IS
BEGIN
(code body here)
END DisplayEmp;
Here is how an error message can be sent back to the client, using one of the pre-coded "jsi" procedures included in the "jsi.sql" library that is provided with Jargon Writer:
MSGBOX.Warning('No such employee number: ' || TO_CHAR(nEmpNo));
Although Jargon Software does not currently supply a source code generator for this host environment, developers are free to implement one, since the generator appname is specified by the "SourceCodeGeneratorApp" preference value in the "writer.ini" file. Please see the "Host Procedures for Oracle PL/SQL" help document for a list of the "jsi" procedures that can be used in PL/SQL to send data and commands from the host to a client app. Writing Java Servlet Host Procedures Java servlets can be easily coded without using a generator. For a simple example, see the "Java/getCust.java" sample servlet included in the Jargon Writer installation directory. This working example has been tested with IBM's WebSphere middleware. Here is how an http input parameter is accessed in a Java servlet:
// Get the parameter values from the input request
String custNum = request.getParameter("custnum");
Here is how an error message can be sent back to the client, using one of the pre-coded "jsi" classes included in the "jargonsoft.jsi" class package that is provided with Jargon Writer:
out.println(msgbox.warning("No such customer number: " + custNum));
Although Jargon Software does not currently supply a source code generator for this host environment, developers are free to implement one, since the generator appname is specified by the "SourceCodeGeneratorApp" preference value in the "writer.ini" file. Please see the "Host Methods for Java" help document for a list of the "jsi" methods that can be used in a Java servlet to send data and commands from the host to a client app. Writing Active Server Pages in VBScript ASP routines can be easily coded without using a generator. For a simple example, see the "asp/triple.asp" sample script included in the Jargon Writer installation directory. This example can be run from the Jargon web site using the "xml/demo32/triple.xml" app. It reads customer credit data from an Access database and can also change the credit limit. Here is how an http input parameter is accessed in VBScript:
Dim cnum
cnum = Request("CustNum")
Here is how an error message can be sent back to the client, using one of the pre-coded "jsi" functions included in the "jsi.asp" library that is provided with Jargon Writer:
Response.Write( jsiWarn("Customer number not found: " & cnum) )
Response.End
Although Jargon Software does not currently supply a source code generator for this host environment, developers are free to implement one, since the generator appname is specified by the "SourceCodeGeneratorApp" preference value in the "writer.ini" file. However, as you can see from the examples, it is not really needed for this environment, because VBScript was designed to make it easy to read and send http data in response to a client http request. Please see the "Host Functions for Microsoft ASP " help document for a list of the "jsi" functions that can be used in an ASP script to send data and commands from the host to a client app. Writing Host Functions with PHP Scripts PHP functions can be easily coded without using a generator. For a stub of a host sync procedure, see the "php/HostSync.php" sample script. For complete syntax examples of all jsi functions, see the "php/jsiTest.asp" sample script included in the Jargon Writer installation directory. This example can be run from a web browser (use View Source to see the output in a more readable format). Here is a handy function that can be used to access http input parameters in PHP:
// get input param from either GET or POST web server values
function GetParam($pParamName) {
$getVal = $_GET[$pParamName];
$postVal = $_POST[$pParamName];
if ($getVal > '') return $getVal;
if ($postVal > '') return $postVal;
return '';
}
// example
$tRep = GetParam('tRep');
Here is how an error message can be sent back to the client, using one of the pre-coded "jsi" functions included in the "jsi.php" library that is provided with Jargon Writer:
jsiWarn("Sales rep ID not found: " . $tRep);
Although Jargon Software does not currently supply a source code generator for this host environment, developers are free to implement one, since the generator appname is specified by the "SourceCodeGeneratorApp" preference value in the "writer.ini" file. However, as you can see from the examples, it is not really needed for this environment, because PHP was designed to make it easy to read and send http data in response to a client http request. Please see the "Host Functions for PHP Scripts " help document for a list of the "jsi" functions that can be used in a PHP script to send data and commands from the host to a client app.
Writing Host Procedures in the Progress 4GL
1. No screen I/O statements are allowed, since the WebSpeed or AppServer agent does not have a direct connection to the client screen. This means that no "DISPLAY", "ASSIGN", "PROMPT-FOR", "SET" or "UPDATE" statements can be used in relation to screen frames, and no screen "frames" or other screen "widgets" can be used with the default input and output streams, nor can INPUT FROM TERMINAL or OUTPUT TO TERMINAL be used.When writing the contents of the include files, you can immediately access the parameters sent from the client by referencing the variables and temp-table records and fields defined in the automatically generated program. Use these values to perform whatever processing is required, such as finding a record in a database table, creating or updating a record, or calculating a total. Then, use the "jsi" include files to create one or more commands to be sent back to the client. These commands may change the contents of a client component (such as displaying a customer name in a textfield) or change the state of a component (such as disabling a button so that it cannot be clicked). New components may also be created dynamically by host commands, with all of the same options for assigning component properties as are available when creating components in Jargon Writer. Other important general-purpose include files allow a host program to invoke any client method on a client object, and to invoke any existing client tasklist to perform whatever actions it specifies. For details of available "jsi" include files, see the Host Methods for Progress 4GL section. Here is how an http input parameter is accessed in the Progress 4GL (this code is normally provided for you by the generator app in the ".p" program):
def var tCustNum as int no-undo.
{jsi/getint.i &fieldname='tCustNum' &targetvar=tCustNum}
Here is how an error message can be sent back to the client, using one of the pre-coded "jsi" include files included in the "jsi" 4GL directory that is provided with Jargon Writer:
def var vMsg as char no-undo.
vMsg = "Customer number not found: " + string(tCustNum).
{jsi/msgbox/warning.i &component='frame0' &msg=vMsg }
Some important syntax rules to remember: 1. A literal character value used as an include parameter should be enclosed in single quotes. This is needed because single quotes are passed through to the referenced include file, and many jsi include files contain nested include files that require quoted parameters to pass through multiple levels of include parameters. (Double quotes are not passed through and do not work correctly for this purpose).
Then, open the client application in Jargon Writer and run it from the Run menu or toolbar button. Test as many different scenarios as possible. If possible, get real end users to test your application. They will often try sequences of actions that were not envisioned when the application was designed, and may expose possible problems that other users could experience. Also, observing a "naive" user (one who did not participate in designing the application) may highlight areas where the user interface is confusing or misleading. If the host request never finishes, the host process may have failed. To view any error messages generated by a host procedure, use a text editor on the host to view the contents of any available log files for the web server, middleware, and language runtime (this varies by type of host environment). When your quality assurance testing is completed, the final step is
to deploy the client and host programs that you have developed. For information
on the various ways to deploy the client-side files, see the Jargon
Software Installation Instructions. The host procedures are deployed
like any other application. You can deploy source files, encrypted source
files, or object files only, depending on your organization's policies
and requirements and your host environment's capabilities in this regard.
|